<!DOCTYPE html><html class="hide-aside" lang="zh-CN" data-theme="light"><head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,user-scalable=no"><title>NPM插件的开发 | Akilarの糖果屋</title><meta name="keywords" content="🌌糖果屋の一千零一夜,🔩NPM插件开发"><meta name="author" content="Akilar"><meta name="copyright" content="Akilar"><meta name="format-detection" content="telephone=no"><meta name="theme-color" content="#ffffff"><meta name="description" content="手把手教导你如何开发一款npm插件，在授人以渔的道路上越走越远"><meta property="og:type" content="article"><meta property="og:title" content="NPM插件的开发"><meta property="og:url" content="https://akilar.top/posts/e44fb560/"><meta property="og:site_name" content="Akilarの糖果屋"><meta property="og:description" content="手把手教导你如何开发一款npm插件，在授人以渔的道路上越走越远"><meta property="og:locale" content="zh_CN"><meta property="og:image" content="https://img.zcool.cn/community/0192b161e57b6011013f01cda2eb5e.jpg?x-oss-process=image/auto-orient,1/resize,m_lfit,w_1280,limit_1/sharpen,100/format,webp/quality,q_100"><meta property="article:published_time" content="2021-06-30T15:51:41.000Z"><meta property="article:modified_time" content="2021-06-30T15:51:41.000Z"><meta property="article:author" content="Akilar"><meta property="article:tag" content="🌌糖果屋の一千零一夜"><meta property="article:tag" content="🔩NPM插件开发"><meta name="twitter:card" content="summary"><meta name="twitter:image" content="https://img.zcool.cn/community/0192b161e57b6011013f01cda2eb5e.jpg?x-oss-process=image/auto-orient,1/resize,m_lfit,w_1280,limit_1/sharpen,100/format,webp/quality,q_100"><link rel="shortcut icon" href="https://npm.elemecdn.com/akiblog@1.0.1/img/siteicon/favicon.png"><link rel="canonical" href="https://akilar.top/posts/e44fb560/" media="defer" onload='this.media="all"'><link rel="preconnect" href="//cdn.jsdelivr.net"><link rel="preconnect" href="//at.alicdn.com/"><link rel="preconnect" href="//cdnjs.cloudflare.com/"><link rel="preconnect" href="//sdk.51.la"><meta name="google_site_verification" content="INnh6jnldNB3hxjSoa9ut7Kd9xX9R6Mqe7807EJsbCc"><meta name="baidu-site-verification" content="code-6O1kXu3a70"><meta name="msvalidate.01" content="3A07763DBFF970229752E8DF7999C30D"><link rel="manifest" href="/manifest.json"><link rel="apple-touch-icon" sizes="180x180" href="https://npm.elemecdn.com/akiblog@1.0.1/img/image/siteicon/apple-touch-icon.png"><link rel="icon" type="image/png" sizes="32x32" href="https://npm.elemecdn.com/akiblog@1.0.1/img/siteicon/favicon-32x32.png"><link rel="icon" type="image/png" sizes="16x16" href="https://npm.elemecdn.com/akiblog@1.0.1/img/siteicon/favicon-16x16.png"><link rel="mask-icon" href="https://npm.elemecdn.com/akiblog@1.0.1/img/siteicon/safari-pinned-tab.svg" color="#5bbad5"><link rel="stylesheet" href="/css/index.css"><link rel="stylesheet" href="https://npm.elemecdn.com/@fortawesome/fontawesome-free@6.1.2/css/all.min.css" media="print" onload='this.media="all"'><link rel="stylesheet" href="https://npm.elemecdn.com/node-snackbar@0.1.16/dist/snackbar.min.css" media="print" onload='this.media="all"'><div class="js-pjax"><script charset="UTF-8" id="LA_COLLECT" src="https://sdk.51.la/js-sdk-pro.min.js"></script><script>LA.init({id:"JdyxkljyWpUOuTqt",ck:"JdyxkljyWpUOuTqt"})</script></div><script src="https://sdk.51.la/perf/js-sdk-perf.min.js" crossorigin="anonymous"></script><script>(new LingQue.Monitor).init({id:"JdzAJUCrdUGoOC7D"})</script><link rel="stylesheet" href="https://npm.elemecdn.com/akiblog@1.0.1/css/animate.min.css" media="print" onload='this.media="screen"'><link rel="stylesheet" href="https://npm.elemecdn.com/swiper@8.4.2/swiper-bundle.min.css" media="print" onload='this.media="all"'><script>const GLOBAL_CONFIG={root:"/",algolia:{appId:"STO7Z288QA",apiKey:"dbcfd77c89c49f19b42d68e572943881",indexName:"akilar",hits:{per_page:3},languages:{input_placeholder:"搜索文章",hits_empty:"找不到您查询的内容：${query}",hits_stats:"找到 ${hits} 条结果，用时 ${time} 毫秒"}},localSearch:void 0,translate:{defaultEncoding:2,translateDelay:0,msgToTraditionalChinese:"<i>繁</i><sapn>簡繁轉換</span>",msgToSimplifiedChinese:"<i>简</i><sapn>简繁转换</span>"},noticeOutdate:{limitDay:30,position:"top",messagePrev:"It has been",messageNext:"days since the last update, the content of the article may be outdated."},highlight:{plugin:"highlighjs",highlightCopy:!0,highlightLang:!0,highlightHeightLimit:130},copy:{success:"吾辈宣布你的剪贴板已经被我占领啦！",error:"抱歉，复制好像出了点问题。",noSupport:"你的浏览器好像不支持"},relativeDate:{homepage:!1,post:!1},runtime:"天",date_suffix:{just:"刚刚",min:"分钟前",hour:"小时前",day:"天前",month:"个月前"},copyright:void 0,lightbox:"mediumZoom",Snackbar:{chs_to_cht:"你已切换为繁体",cht_to_chs:"你已切换为简体",day_to_night:"你已切换为深色模式",night_to_day:"你已切换为浅色模式",bgLight:"#49B1F5",bgDark:"#1f1f1f",position:"top-center"},source:{justifiedGallery:{js:"https://npm.elemecdn.com/flickr-justified-gallery@2.1.2/dist/fjGallery.min.js",css:"https://npm.elemecdn.com/flickr-justified-gallery@2.1.2/dist/fjGallery.css"}},isPhotoFigcaption:!0,islazyload:!0,isAnchor:!1}</script><script id="config-diff">var GLOBAL_CONFIG_SITE={title:"NPM插件的开发",isPost:!0,isHome:!1,isHighlightShrink:!1,isToc:!0,postUpdate:"2021-06-30 15:51:41"}</script><noscript><style>#nav{opacity:1}.justified-gallery img{opacity:1}#post-meta time,#recent-posts time{display:inline!important}</style></noscript><script>(e=>{e.saveToLocal={set:function(e,t,o){if(0===o)return;const a=864e5*o,n={value:t,expiry:(new Date).getTime()+a};localStorage.setItem(e,JSON.stringify(n))},get:function(e){const t=localStorage.getItem(e);if(!t)return;const o=JSON.parse(t);if(!((new Date).getTime()>o.expiry))return o.value;localStorage.removeItem(e)}},e.getScript=e=>new Promise((t,o)=>{const a=document.createElement("script");a.src=e,a.async=!0,a.onerror=o,a.onload=a.onreadystatechange=function(){const e=this.readyState;e&&"loaded"!==e&&"complete"!==e||(a.onload=a.onreadystatechange=null,t())},document.head.appendChild(a)}),e.activateDarkMode=function(){document.documentElement.setAttribute("data-theme","dark"),null!==document.querySelector('meta[name="theme-color"]')&&document.querySelector('meta[name="theme-color"]').setAttribute("content","#0d0d0d")},e.activateLightMode=function(){document.documentElement.setAttribute("data-theme","light"),null!==document.querySelector('meta[name="theme-color"]')&&document.querySelector('meta[name="theme-color"]').setAttribute("content","#ffffff")};const t=saveToLocal.get("theme"),o=(new Date).getHours();void 0===t?o<=6||o>=18?activateDarkMode():activateLightMode():"light"===t?activateLightMode():activateDarkMode();const a=saveToLocal.get("aside-status");void 0!==a&&("hide"===a?document.documentElement.classList.add("hide-aside"):document.documentElement.classList.remove("hide-aside"));/iPad|iPhone|iPod|Macintosh/.test(navigator.userAgent)&&document.documentElement.classList.add("apple")})(window)</script><link rel="stylesheet" href="https://npm.elemecdn.com/akiblog@1.0.1/css/custom.css" media="defer" onload='this.media="all"'><link rel="stylesheet" href="https://widget.heweather.net/simple/static/css/he-simple.css?v=1.4.0" media="defer" onload='this.media="all"'><script src="https://npm.elemecdn.com/akiblog@1.0.1/js/custom/SAO-Notify.js" async></script><script async src="https://npm.elemecdn.com/akiblog@1.0.1/js/custom/carousel-touch.js"></script><svg aria-hidden="true" style="position:absolute;overflow:hidden;width:0;height:0"><symbol id="icon-sun" viewBox="0 0 1024 1024"><path d="M960 512l-128 128v192h-192l-128 128-128-128H192v-192l-128-128 128-128V192h192l128-128 128 128h192v192z" fill="#FFD878" p-id="8420"></path><path d="M736 512a224 224 0 1 0-448 0 224 224 0 1 0 448 0z" fill="#FFE4A9" p-id="8421"></path><path d="M512 109.248 626.752 224H800v173.248L914.752 512 800 626.752V800h-173.248L512 914.752 397.248 800H224v-173.248L109.248 512 224 397.248V224h173.248L512 109.248M512 64l-128 128H192v192l-128 128 128 128v192h192l128 128 128-128h192v-192l128-128-128-128V192h-192l-128-128z" fill="#4D5152" p-id="8422"></path><path d="M512 320c105.888 0 192 86.112 192 192s-86.112 192-192 192-192-86.112-192-192 86.112-192 192-192m0-32a224 224 0 1 0 0 448 224 224 0 0 0 0-448z" fill="#4D5152" p-id="8423"></path></symbol><symbol id="icon-moon" viewBox="0 0 1024 1024"><path d="M611.370667 167.082667a445.013333 445.013333 0 0 1-38.4 161.834666 477.824 477.824 0 0 1-244.736 244.394667 445.141333 445.141333 0 0 1-161.109334 38.058667 85.077333 85.077333 0 0 0-65.066666 135.722666A462.08 462.08 0 1 0 747.093333 102.058667a85.077333 85.077333 0 0 0-135.722666 65.024z" fill="#FFB531" p-id="11345"></path><path d="M329.728 274.133333l35.157333-35.157333a21.333333 21.333333 0 1 0-30.165333-30.165333l-35.157333 35.157333-35.114667-35.157333a21.333333 21.333333 0 0 0-30.165333 30.165333l35.114666 35.157333-35.114666 35.157334a21.333333 21.333333 0 1 0 30.165333 30.165333l35.114667-35.157333 35.157333 35.157333a21.333333 21.333333 0 1 0 30.165333-30.165333z" fill="#030835" p-id="11346"></path></symbol></svg><link rel="stylesheet" href="https://npm.elemecdn.com/hexo-filter-gitcalendar/lib/gitcalendar.css" media="print" onload='this.media="all"'><meta name="generator" content="Hexo 6.2.0"><link rel="alternate" href="/atom.xml" title="Akilarの糖果屋" type="application/atom+xml"></head><body><div id="loading-box"><div class="ark-loading" id="ark-loading"><div class="ark-loading-top-container"><div class="ark-loading-top-left-flash"></div><div class="ark-loading-top-left-border"></div><div class="ark-loading-top-triangle"></div><div class="ark-loading-top-right-border"></div><div class="ark-loading-top-right-flash"></div></div><div class="ark-loading-bottom-container"><div class="ark-loading-bottom-left-border"></div><div class="ark-loading-bottom-left-triangle"></div><div class="ark-loading-bottom-center-border"></div><div class="ark-loading-bottom-right-triangle"></div><div class="ark-loading-bottom-right-border"></div></div><div class="ark-loading-main-container"><div class="ark-loading-content"><div class="ark-loading-power-left"></div><div class="ark-loading-center-left-border"></div><div class="ark-loading-cab-outside-border"><div class="ark-loading-cab-insideborder"><div class="ark-loading-cab-container"><div class="ark-loading-percentage"></div><div class="ark-loading-tip"></div></div></div></div><div class="ark-loading-center-right-border"></div><div class="ark-loading-power-right"></div></div></div></div></div><div id="web_bg"></div><div id="sidebar"><div id="menu-mask"></div><div id="sidebar-menus"><div class="avatar-img is-center"><img src="" data-lazy-src="https://npm.elemecdn.com/akiblog@1.0.1/img/author.webp" onerror='onerror=null,src="https://npm.elemecdn.com/akiblog@1.0.1/img/404.gif"' alt="avatar"></div><div class="sidebar-site-data site-data is-center"><a href="/archives/"><div class="headline">文章</div><div class="length-num">480</div></a><a href="/tags/"><div class="headline">标签</div><div class="length-num">63</div></a><a href="/categories/"><div class="headline">分类</div><div class="length-num">6</div></a></div><hr><div class="menus_items"><div class="menus_item"><a class="site-page faa-parent animated-hover" href="/"><svg class="icon faa-tada" aria-hidden="true"><use xlink:href="#icon-laptop"></use></svg> <span>博客</span></a></div><div class="menus_item"><a class="site-page faa-parent animated-hover" href="/archives/"><svg class="icon faa-tada" aria-hidden="true"><use xlink:href="#icon-Calendar"></use></svg> <span>时间轴</span></a></div><div class="menus_item"><a class="site-page faa-parent animated-hover" href="/tags/"><svg class="icon faa-tada" aria-hidden="true"><use xlink:href="#icon-strategy"></use></svg> <span>标签</span></a></div><div class="menus_item"><a class="site-page faa-parent animated-hover" href="/fcircle/"><svg class="icon faa-tada" aria-hidden="true"><use xlink:href="#icon-forumdiscusstion"></use></svg> <span>朋友圈</span></a></div><div class="menus_item"><a class="site-page faa-parent animated-hover" href="/link/"><svg class="icon faa-tada" aria-hidden="true"><use xlink:href="#icon-connection"></use></svg> <span>友人帐</span></a></div><div class="menus_item"><a class="site-page faa-parent animated-hover" href="/comments/"><svg class="icon faa-tada" aria-hidden="true"><use xlink:href="#icon-letter"></use></svg> <span>留言板</span></a></div><div class="menus_item"><a class="site-page group faa-parent animated-hover" href="javascript:void(0);" rel="external nofollow noreferrer"><svg class="icon faa-tada" aria-hidden="true"><use xlink:href="#icon-hourglass"></use></svg> <span>生活</span><i class="fas fa-chevron-down expand"></i></a><ul class="menus_item_child"><li><a class="faa-parent animated-hover site-page child" href="/gallery/"><svg class="icon faa-tada" aria-hidden="true"><use xlink:href="#icon-strategy"></use></svg> <span>相册</span></a></li><li><a class="faa-parent animated-hover site-page child" href="/bangumis/"><svg class="icon faa-tada" aria-hidden="true"><use xlink:href="#icon-unicorn"></use></svg> <span>追番</span></a></li><li><a class="faa-parent animated-hover site-page child" href="/about/"><svg class="icon faa-tada" aria-hidden="true"><use xlink:href="#icon-Achievement"></use></svg> <span>关于</span></a></li></ul></div><div class="menus_item"><a class="site-page faa-parent animated-hover" href="javascript:toRandomPost()" rel="external nofollow noreferrer"><svg class="icon faa-tada" aria-hidden="true"><use xlink:href="#icon-teamwork"></use></svg> <span>随便看看</span></a></div></div></div></div><div class="post" id="body-wrap"><header class="post-bg" id="page-header" style="background-image:url(https://img.zcool.cn/community/0192b161e57b6011013f01cda2eb5e.jpg?x-oss-process=image/auto-orient,1/resize,m_lfit,w_1280,limit_1/sharpen,100/format,webp/quality,q_100)"><div class="menu-container" id="menu-container"><div class="menu-item"><div class="menu-item-main"><a class="site-page faa-parent animated-hover" href="/"><svg class="icon faa-tada" aria-hidden="true"><use xlink:href="#icon-laptop"></use></svg> <span>博客</span></a></div><div class="menu-item-main"><a class="site-page faa-parent animated-hover" href="/archives/"><svg class="icon faa-tada" aria-hidden="true"><use xlink:href="#icon-Calendar"></use></svg> <span>时间轴</span></a></div><div class="menu-item-main"><a class="site-page faa-parent animated-hover" href="/tags/"><svg class="icon faa-tada" aria-hidden="true"><use xlink:href="#icon-strategy"></use></svg> <span>标签</span></a></div><div class="menu-item-main"><a class="site-page faa-parent animated-hover" href="/fcircle/"><svg class="icon faa-tada" aria-hidden="true"><use xlink:href="#icon-forumdiscusstion"></use></svg> <span>朋友圈</span></a></div><div class="menu-item-main"><a class="site-page faa-parent animated-hover" href="/link/"><svg class="icon faa-tada" aria-hidden="true"><use xlink:href="#icon-connection"></use></svg> <span>友人帐</span></a></div><div class="menu-item-main"><a class="site-page faa-parent animated-hover" href="/comments/"><svg class="icon faa-tada" aria-hidden="true"><use xlink:href="#icon-letter"></use></svg> <span>留言板</span></a></div><div class="menu-item-main has-child"><div class="menu-item-parent"><a class="site-page faa-parent animated-hover" href="javascript:void(0);" rel="external nofollow noreferrer"><svg class="icon faa-tada" aria-hidden="true"><use xlink:href="#icon-hourglass"></use></svg> <span>生活</span></a></div><div class="menu-item-child"><a class="faa-parent animated-hover site-page child" href="/gallery/"><svg class="icon faa-tada" aria-hidden="true"><use xlink:href="#icon-strategy"></use></svg> <span>相册</span></a></div><div class="menu-item-child"><a class="faa-parent animated-hover site-page child" href="/bangumis/"><svg class="icon faa-tada" aria-hidden="true"><use xlink:href="#icon-unicorn"></use></svg> <span>追番</span></a></div><div class="menu-item-child"><a class="faa-parent animated-hover site-page child" href="/about/"><svg class="icon faa-tada" aria-hidden="true"><use xlink:href="#icon-Achievement"></use></svg> <span>关于</span></a></div></div><div class="menu-item-main"><a class="site-page faa-parent animated-hover" href="javascript:toRandomPost()" rel="external nofollow noreferrer"><svg class="icon faa-tada" aria-hidden="true"><use xlink:href="#icon-teamwork"></use></svg> <span>随便看看</span></a></div></div><div class="top-bar"><div class="message-container"><div class="message-item message-weather" onclick="btf.scrollToDest(0,500)"><div class="message-weather-box" id="he-plugin-simple"></div></div><div class="message-item message-date" onclick="Navvisible()"><div class="message-date-box" id="message-date-box"></div><div class="message-title-box" id="message-title-box"><a id="site-name" title="手把手教导你如何开发一款npm插件，在授人以渔的道路上越走越远">糖果屋の一千零一夜</a></div></div><div class="message-item message-function"><div id="search-button"><a class="site-page social-icon search faa-parent animated-hover"><svg class="faa-tada icon" style="height:25px;width:25px" aria-hidden="true"><use xlink:href="#icon-analitic"></use></svg> <span>搜索</span></a></div><a class="icon-V hidden faa-parent animated-hover" onclick="switchNightMode()" title="昼夜切换"><svg class="faa-tada" width="25" height="25" viewBox="0 0 1024 1024"><use id="modeicon" xlink:href="#icon-moon"></use></svg></a><div id="toggle-menu"><a class="site-page faa-parent animated-hover"><svg class="faa-tada icon" style="height:25px;width:25px" aria-hidden="true"><use xlink:href="#icon-MobileApps"></use></svg></a></div></div></div></div><button class="active-button" onclick="Navvisible()"></button></div><div id="post-info"><h1 class="post-title">NPM插件的开发<a class="post-edit-link" href="https://github.com/Akilarlxh/Hexo-blog-source/edit/master/source/_posts/Akilarの糖葫芦/写作技巧/npm插件的开发记录.md" rel="external nofollow noreferrer" title="编辑" target="_blank"><i class="fas fa-feather-alt faa-tada animated-hover"></i></a></h1><div id="post-meta"><div class="meta-firstline"><span class="post-meta-date"><i class="far fa-calendar-alt fa-fw post-meta-icon"></i><span class="post-meta-label">发表于</span><time class="post-meta-date-created" datetime="2021-06-30T15:51:41.000Z" title="发表于 2021-06-30 15:51:41">2021-06-30</time><span class="post-meta-separator">|</span><i class="fas fa-history fa-fw post-meta-icon"></i><span class="post-meta-label">更新于</span><time class="post-meta-date-updated" datetime="2021-06-30T15:51:41.000Z" title="更新于 2021-06-30 15:51:41">2021-06-30</time></span><span class="post-meta-categories"><span class="post-meta-separator">|</span><i class="fas fa-inbox fa-fw post-meta-icon"></i><a class="post-meta-categories" href="/categories/%F0%9F%8D%A1Akilar%E3%81%AE%E7%B3%96%E8%91%AB%E8%8A%A6/">🍡Akilarの糖葫芦</a></span></div><div class="meta-secondline"><span class="post-meta-separator">|</span><span class="post-meta-wordcount"><i class="far fa-file-word fa-fw post-meta-icon"></i><span class="post-meta-label">字数总计:</span><span class="word-count">5.6k</span><span class="post-meta-separator">|</span><i class="far fa-clock fa-fw post-meta-icon"></i><span class="post-meta-label">阅读时长:</span><span>22分钟</span></span></div></div></div></header><main class="layout" id="content-inner"><div id="post"><article class="post-content" id="article-container"><details class="folding-tag" cyan><summary>点击查看更新记录</summary><div class="content"><div class="timeline undefined"><div class="timeline-item headline"><div class="timeline-item-title"><div class="item-circle"><p>更新记录</p></div></div></div><div class="timeline-item"><div class="timeline-item-title"><div class="item-circle"><p>2021-06-30:初步讲解可能用到的api</p></div></div><div class="timeline-item-content"><ol><li>hexo过滤器（Filter）API用法</li><li>hexo生成器（Generator）API用法</li><li>hexo注入器（Injector）API用法</li><li>hexo辅助函数（Helper）API简单用法</li></ol></div></div></div></div></details><details class="folding-tag" yellow><summary>点击查看参考教程</summary><div class="content"><div class="table-container"><table><thead><tr><th style="text-align:left">参考方向</th><th style="text-align:left">教程原贴</th></tr></thead><tbody><tr><td style="text-align:left">高情商：有效治疗低血压患者</td><td style="text-align:left"><a target="_blank" rel="noopener external nofollow noreferrer" href="https://hexo.io/zh-cn/api/">Hexo API文档</a></td></tr><tr><td style="text-align:left">参考了页面生成插件的写法</td><td style="text-align:left"><a class="ghcard" rel="external nofollow noopener noreferrer noopener" target="_blank" href="https://github.com/jerryc127/butterfly-plugins"><img class="no-lightbox" src="" data-lazy-src="https://github-readme-stats.vercel.app/api/pin/?username=jerryc127&repo=butterfly-plugins&show_owner=true"></a></td></tr><tr><td style="text-align:left">参考了页面植入式插件的写法，以及hexo api的具体应用</td><td style="text-align:left"><a class="ghcard" rel="external nofollow noopener noreferrer noopener" target="_blank" href="https://github.com/Zfour/hexo-swiper-bar"><img class="no-lightbox" src="" data-lazy-src="https://github-readme-stats.vercel.app/api/pin/?username=Zfour&repo=hexo-swiper-bar&show_owner=true"></a></td></tr><tr><td style="text-align:left">编译stylus文件</td><td style="text-align:left"><a target="_blank" rel="noopener external nofollow noreferrer" href="https://www.stylus-lang.cn/">stylus官方文档</a></td></tr><tr><td style="text-align:left">编译pug文件</td><td style="text-align:left"><a target="_blank" rel="noopener external nofollow noreferrer" href="https://www.npmjs.com/package/pug">PUG官方文档</a></td></tr></tbody></table></div></div></details><details class="folding-tag" red><summary>店长的碎碎念</summary><div class="content"><p>本文讨论的npm插件化，针对的是那种可以放在单独的页面魔改，或者代码可以剥离出来，通过某个特定的页面容器进行挂载的植入式魔改方案。</p><p>例如糖果屋的gitcalendar，页面轮播图，以及所有的侧栏魔改就是植入式插件。而信封式留言板，朋友圈前端页面则是页面式插件。<del>糖果屋微调合集基本上是不可能写成插件了。倒不是说理论上不可行。而是时间成本不对等。毕竟改10行代码的事情非要去写几十行的插件，得不偿失。</del></p><p>它们的共同特点就是<span class="nota" data-nota="高内聚低耦合，是软件工程中的概念，是判断软件设计好坏的标准，主要用于程序的面向对象的设计，主要看类的内聚性是否高，耦合度是否低。目的是使程序模块的可重用性、移植性大大增强。通常程序结构中各模块的内聚程度越高，模块间的耦合程度就越低。内聚是从功能角度来度量模块内的联系，一个好的内聚模块应当恰好做一件事，它描述的是模块内的功能联系；耦合是软件结构中各模块之间相互连接的一种度量，耦合强弱取决于模块间接口的复杂程度、进入或访问一个模块的点以及通过接口的数据。">高内聚低耦合</span>。除了必要的挂载容器以及适配样式和主题相关以外，理论上可以把它们迁移到任何其他主题。<br>这就给魔改方案普及化提供了可能性。只需要更换挂载容器或者附加一些样式补丁，我们就能很轻易的在其他主题也用上这些方案。<br>本文提供的详细的教程拆解和具体示例。</p></div></details><h2 id="NPM插件的发布"><a href="#NPM插件的发布" class="headerlink" title="NPM插件的发布"></a>NPM插件的发布</h2><p>此部分内容已经在<a href="/posts/3e956346/">NPM图床的使用技巧</a>中进行过详细描述。关于账户注册和插件发布的部分本帖不会再详细展开。以下仅针对本地开发流程进行阐述。</p><h2 id="教程拆解"><a href="#教程拆解" class="headerlink" title="教程拆解"></a>教程拆解</h2><details class="folding-tag" red open><summary>点击折叠教程内容</summary><div class="content"><ol><li>新建文件夹，在里面运行<code>npm init</code>以后，按照指示，初始化<code>npm</code>插件。我们首先会获得一个<code>package.json</code>。以下是我的<code>package.json</code>内容。此处除了初始化默认生成的内容外，我还指定了<code>pug</code>依赖的版本,没有特殊版本需求的话，不写其实也没有关系。<figure class="highlight json"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br></pre></td><td class="code"><pre><span class="line"><span class="punctuation">&#123;</span></span><br><span class="line">  <span class="attr">&quot;name&quot;</span><span class="punctuation">:</span> <span class="string">&quot;hexo-butterfly-artitalk-pro&quot;</span><span class="punctuation">,</span></span><br><span class="line">  <span class="attr">&quot;version&quot;</span><span class="punctuation">:</span> <span class="string">&quot;0.0.1&quot;</span><span class="punctuation">,</span></span><br><span class="line">  <span class="attr">&quot;description&quot;</span><span class="punctuation">:</span> <span class="string">&quot;A talk plugin for theme-butterfly based on artitalk&quot;</span><span class="punctuation">,</span></span><br><span class="line">  <span class="attr">&quot;main&quot;</span><span class="punctuation">:</span> <span class="string">&quot;index.js&quot;</span><span class="punctuation">,</span></span><br><span class="line">  <span class="attr">&quot;scripts&quot;</span><span class="punctuation">:</span> <span class="punctuation">&#123;</span></span><br><span class="line">    <span class="attr">&quot;eslint&quot;</span><span class="punctuation">:</span> <span class="string">&quot;eslint .&quot;</span></span><br><span class="line">  <span class="punctuation">&#125;</span><span class="punctuation">,</span></span><br><span class="line">  <span class="attr">&quot;directories&quot;</span><span class="punctuation">:</span> <span class="punctuation">&#123;</span></span><br><span class="line">    <span class="attr">&quot;lib&quot;</span><span class="punctuation">:</span> <span class="string">&quot;./lib&quot;</span></span><br><span class="line">  <span class="punctuation">&#125;</span><span class="punctuation">,</span></span><br><span class="line">  <span class="attr">&quot;files&quot;</span><span class="punctuation">:</span> <span class="punctuation">[</span></span><br><span class="line">    <span class="string">&quot;lib/&quot;</span><span class="punctuation">,</span></span><br><span class="line">    <span class="string">&quot;index.js&quot;</span></span><br><span class="line">  <span class="punctuation">]</span><span class="punctuation">,</span></span><br><span class="line">  <span class="attr">&quot;keywords&quot;</span><span class="punctuation">:</span> <span class="punctuation">[</span></span><br><span class="line">    <span class="string">&quot;hexo&quot;</span><span class="punctuation">,</span></span><br><span class="line">    <span class="string">&quot;filter&quot;</span><span class="punctuation">,</span></span><br><span class="line">    <span class="string">&quot;artitalk&quot;</span><span class="punctuation">,</span></span><br><span class="line">    <span class="string">&quot;butterfly&quot;</span><span class="punctuation">,</span></span><br><span class="line">    <span class="string">&quot;theme-butterfly&quot;</span><span class="punctuation">,</span></span><br><span class="line">    <span class="string">&quot;sidebar&quot;</span><span class="punctuation">,</span></span><br><span class="line">    <span class="string">&quot;plugins&quot;</span></span><br><span class="line">  <span class="punctuation">]</span><span class="punctuation">,</span></span><br><span class="line">  <span class="attr">&quot;author&quot;</span><span class="punctuation">:</span> <span class="string">&quot;akilarlxh&quot;</span><span class="punctuation">,</span></span><br><span class="line">  <span class="attr">&quot;license&quot;</span><span class="punctuation">:</span> <span class="string">&quot;Apache-2.0&quot;</span><span class="punctuation">,</span></span><br><span class="line">  <span class="attr">&quot;dependencies&quot;</span><span class="punctuation">:</span> <span class="punctuation">&#123;</span></span><br><span class="line">    <span class="attr">&quot;pug&quot;</span><span class="punctuation">:</span> <span class="string">&quot;^3.0.0&quot;</span></span><br><span class="line">  <span class="punctuation">&#125;</span><span class="punctuation">,</span></span><br><span class="line">  <span class="attr">&quot;repository&quot;</span><span class="punctuation">:</span> <span class="punctuation">&#123;</span></span><br><span class="line">    <span class="attr">&quot;type&quot;</span><span class="punctuation">:</span> <span class="string">&quot;git&quot;</span><span class="punctuation">,</span></span><br><span class="line">    <span class="attr">&quot;url&quot;</span><span class="punctuation">:</span> <span class="string">&quot;https://github.com/Akilarlxh/hexo-butterfly-artitalk-pro.git&quot;</span></span><br><span class="line">  <span class="punctuation">&#125;</span></span><br><span class="line"><span class="punctuation">&#125;</span></span><br></pre></td></tr></table></figure></li><li>然后是新建三个文件（或者文件目录），<ul><li><code>index.js</code>，这是插件的主要脚本，负责处理各类数据和进行插件植入操作。</li><li><code>README.md</code>，这是插件文档，你可以把它认为是你插件的说明书。出于开发者的专业素养，建议详细编写你的插件文档。</li><li><code>lib/</code>，这个目录下我们预计存放一些静态资源。当然你也不一定非要在这里放静态资源。放在根目录也同样可以。专门建个资源目录只是为了便于管理而已。</li></ul></li><li>在编写一款hexo插件之前，我们应当确认会用到哪些配置项。<div class="tabs" id="plugins-"><ul class="nav-tabs"><li class="tab active"><button type="button" data-href="#plugins--1">容器挂载型</button></li><li class="tab"><button type="button" data-href="#plugins--2">页面生成型</button></li></ul><div class="tab-contents"><div class="tab-item-content active" id="plugins--1"><p>以容器挂载型插件为例,必要的内容有插件开关，<span class="nota" data-nota="当有多个植入插件在同一个容器内请求挂载时，就需要用到过滤器优先权来决定他们的执行顺序，数字越小，则优先权越高，相对就越早执行。">过滤器优先权</span>，应用页面，挂载容器、<span class="nota" data-nota="此处拟采用原理为将屏蔽项的内容逐个放到当前路径去匹配，若当前路径包含任一屏蔽项，则不会挂载。">屏蔽页面</span>。<br></p><figure class="highlight yml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line"><span class="attr">config_name:</span></span><br><span class="line">  <span class="attr">enable:</span> <span class="literal">true</span> <span class="comment"># 开关</span></span><br><span class="line">  <span class="attr">priority:</span> <span class="number">5</span> <span class="comment">#过滤器优先权</span></span><br><span class="line">  <span class="attr">enable_page:</span> <span class="string">all</span> <span class="comment"># 应用页面</span></span><br><span class="line">  <span class="attr">exclude:</span></span><br><span class="line">    <span class="bullet">-</span> <span class="string">/posts/</span> <span class="comment">#需要配合abbrlink插件</span></span><br><span class="line">  <span class="attr">layout:</span> <span class="comment"># 挂载容器类型</span></span><br><span class="line">    <span class="attr">type:</span> <span class="string">class</span></span><br><span class="line">    <span class="attr">name:</span> <span class="string">sticky_layout</span></span><br><span class="line">    <span class="attr">index:</span> <span class="number">0</span></span><br></pre></td></tr></table></figure><p></p><button type="button" class="tab-to-top" aria-label="scroll to top"><i class="fas fa-arrow-up"></i></button></div><div class="tab-item-content" id="plugins--2"><p>以页面生成型插件为例,必要的内容有插件开关，页面生成路径,<span class="nota" data-nota="此处指页面的特有变量">front_matter</span>。<br></p><figure class="highlight yml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="attr">config_name:</span></span><br><span class="line">  <span class="attr">enable:</span> <span class="literal">true</span> <span class="comment">#开关</span></span><br><span class="line">  <span class="attr">path:</span> <span class="comment">#生成的页面路径</span></span><br><span class="line">  <span class="attr">front_matter:</span> <span class="comment">#页面的front_matter</span></span><br><span class="line">    <span class="attr">title:</span></span><br><span class="line">    <span class="attr">description:</span></span><br></pre></td></tr></table></figure><p></p><button type="button" class="tab-to-top" aria-label="scroll to top"><i class="fas fa-arrow-up"></i></button></div></div></div></li><li>在确定变量以后，我们就可以开始在<code>index.js</code>中编写插件的具体内容了。<div class="tabs" id="indexjs"><ul class="nav-tabs"><li class="tab active"><button type="button" data-href="#indexjs-1">容器挂载型</button></li><li class="tab"><button type="button" data-href="#indexjs-2">页面生成型</button></li></ul><div class="tab-contents"><div class="tab-item-content active" id="indexjs-1"><ul><li>以容器挂载型为例。首先是整体的文件目录结构<figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line">|__lib</span><br><span class="line">  |__html.pug  <span class="comment">#插件的主要dom结构</span></span><br><span class="line">  |__style.css <span class="comment">#可能用到的自定义样式</span></span><br><span class="line">  |__script.js <span class="comment">#可能用到的自定义脚本</span></span><br><span class="line">|__index.js</span><br><span class="line">|__package.json</span><br></pre></td></tr></table></figure></li><li>打开<code>index.js</code>,开始编写脚本。请详细阅读以下代码中的注释。我会尽量逐行解释。为了便于区分，我们约定不再变动的为常量，用<code>const</code>声明。会变动的为变量，用<code>var</code>声明。（事实上在这个<code>index.js</code>中，<code>const</code>和<code>var</code>的生命周期没多大意义了。就算全部用<code>var</code>也没事）<br><div class="note info flat"><p>考虑到以下代码内容较多，建议复制到自己的编辑器内进行查看。您也可以将以下代码作为通用模板进行修改，来编写属于您自己的插件。</p></div><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br><span class="line">83</span><br><span class="line">84</span><br><span class="line">85</span><br><span class="line">86</span><br><span class="line">87</span><br><span class="line">88</span><br><span class="line">89</span><br><span class="line">90</span><br><span class="line">91</span><br><span class="line">92</span><br><span class="line">93</span><br><span class="line">94</span><br><span class="line">95</span><br><span class="line">96</span><br><span class="line">97</span><br><span class="line">98</span><br><span class="line">99</span><br><span class="line">100</span><br><span class="line">101</span><br><span class="line">102</span><br><span class="line">103</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">&#x27;use strict&#x27;</span></span><br><span class="line"><span class="comment">// 全局声明插件代号，插件的名字随你定</span></span><br><span class="line"><span class="comment">// 此处是为了便于区分多个插件的注入函数名，确保不重名。</span></span><br><span class="line"><span class="keyword">const</span> pluginname = <span class="string">&#x27;plugin_name&#x27;</span></span><br><span class="line"><span class="comment">// 全局声明依赖，此处用到的都是hexo的api或者pug插件的api</span></span><br><span class="line"><span class="keyword">const</span> pug = <span class="built_in">require</span>(<span class="string">&#x27;pug&#x27;</span>)</span><br><span class="line"><span class="keyword">const</span> path = <span class="built_in">require</span>(<span class="string">&#x27;path&#x27;</span>)</span><br><span class="line"><span class="keyword">const</span> urlFor = <span class="built_in">require</span>(<span class="string">&#x27;hexo-util&#x27;</span>).<span class="property">url_for</span>.<span class="title function_">bind</span>(hexo)</span><br><span class="line"><span class="keyword">const</span> util = <span class="built_in">require</span>(<span class="string">&#x27;hexo-util&#x27;</span>)</span><br><span class="line"></span><br><span class="line">hexo.<span class="property">extend</span>.<span class="property">filter</span>.<span class="title function_">register</span>(<span class="string">&#x27;after_generate&#x27;</span>, <span class="keyword">function</span> (<span class="params"></span>) &#123;</span><br><span class="line">  <span class="comment">// 首先获取整体的配置项名称,</span></span><br><span class="line">  <span class="comment">// 这行的写法可以保证不管是写在主题配置文件里</span></span><br><span class="line">  <span class="comment">// 还是站点配置文件里，都能读取到配置项。</span></span><br><span class="line">  <span class="keyword">const</span> config = hexo.<span class="property">config</span>.<span class="property">config_name</span> || hexo.<span class="property">theme</span>.<span class="property">config</span>.<span class="property">config_name</span></span><br><span class="line">  <span class="comment">// 如果配置开启</span></span><br><span class="line">  <span class="keyword">if</span> (!(config &amp;&amp; config.<span class="property">enable</span>)) <span class="keyword">return</span></span><br><span class="line">  <span class="comment">// 集体声明配置项，将我们用到的配置项全部封装到data里</span></span><br><span class="line">  <span class="comment">// 之后方便我们统一调用。</span></span><br><span class="line">  <span class="comment">// 同时活用三元运算符，给配置项设置默认配置内容。</span></span><br><span class="line">    <span class="keyword">const</span> data = &#123;</span><br><span class="line">      <span class="attr">enable_page</span>: config.<span class="property">enable_page</span> ? config.<span class="property">enable_page</span> : <span class="string">&quot;all&quot;</span>,</span><br><span class="line">      <span class="attr">exclude</span>: config.<span class="property">exclude</span>,</span><br><span class="line">      <span class="attr">layout_type</span>: config.<span class="property">layout</span>.<span class="property">type</span>,</span><br><span class="line">      <span class="attr">layout_name</span>: config.<span class="property">layout</span>.<span class="property">name</span>,</span><br><span class="line">      <span class="attr">layout_index</span>: config.<span class="property">layout</span>.<span class="property">index</span> ? config.<span class="property">layout</span>.<span class="property">index</span> : <span class="number">0</span></span><br><span class="line">    &#125;</span><br><span class="line">  <span class="comment">// 渲染页面，此处调用了pug的api，具体写法可以查看最上方的参考教程。</span></span><br><span class="line">  <span class="keyword">const</span> temple_html_text = config.<span class="property">temple_html</span> ? config.<span class="property">temple_html</span> : pug.<span class="title function_">renderFile</span>(path.<span class="title function_">join</span>(__dirname, <span class="string">&#x27;./lib/html.pug&#x27;</span>),data)</span><br><span class="line">  <span class="comment">//cdn资源声明，来引用必要的依赖或者样式。</span></span><br><span class="line">    <span class="comment">//样式资源</span></span><br><span class="line">  <span class="keyword">const</span> css_text = <span class="string">`&lt;link rel=&quot;stylesheet&quot; href=&quot;https://npm.elemecdn.com/package_name/lib/style.css&quot;&gt;`</span></span><br><span class="line">    <span class="comment">//脚本资源</span></span><br><span class="line">  <span class="keyword">const</span> js_text = <span class="string">`&lt;script src=&quot;https://npm.elemecdn.com/package_name/lib/script.js&quot;&gt;&lt;/script&gt;`</span></span><br><span class="line">  <span class="comment">//注入容器声明，用来判断注入容器类型。</span></span><br><span class="line">  <span class="comment">// ==========start=============</span></span><br><span class="line">  <span class="keyword">var</span> get_layout</span><br><span class="line">  <span class="comment">//若指定为class类型的容器</span></span><br><span class="line">  <span class="comment">// 因为各个配置项内容已经封装在data数据集里</span></span><br><span class="line">  <span class="comment">// 我们就需要用data.name的方式来访问</span></span><br><span class="line">  <span class="keyword">if</span> (data.<span class="property">layout_type</span> === <span class="string">&#x27;class&#x27;</span>) &#123;</span><br><span class="line">    <span class="comment">//则根据class类名及序列获取容器</span></span><br><span class="line">    get_layout = <span class="string">`document.getElementsByClassName(&#x27;<span class="subst">$&#123;data.layout_name&#125;</span>&#x27;)[<span class="subst">$&#123;data.layout_index&#125;</span>]`</span></span><br><span class="line">  &#125;</span><br><span class="line">  <span class="comment">// 若指定为id类型的容器</span></span><br><span class="line">  <span class="keyword">else</span> <span class="keyword">if</span> (data.<span class="property">layout_type</span> === <span class="string">&#x27;id&#x27;</span>) &#123;</span><br><span class="line">    <span class="comment">// 直接根据id获取容器</span></span><br><span class="line">    get_layout = <span class="string">`document.getElementById(&#x27;<span class="subst">$&#123;data.layout_name&#125;</span>&#x27;)`</span></span><br><span class="line">  &#125;</span><br><span class="line">  <span class="comment">// 若未指定容器类型，默认使用id查询</span></span><br><span class="line">  <span class="keyword">else</span> &#123;</span><br><span class="line">    get_layout = <span class="string">`document.getElementById(&#x27;<span class="subst">$&#123;data.layout_name&#125;</span>&#x27;)`</span></span><br><span class="line">  &#125;</span><br><span class="line">  <span class="comment">// =============end===============</span></span><br><span class="line">  <span class="comment">//挂载容器脚本，用来注入上方编译好的插件dom结构</span></span><br><span class="line">  <span class="comment">//挂载容器脚本</span></span><br><span class="line">  <span class="keyword">var</span> user_info_js = <span class="string">`&lt;script data-pjax&gt;</span></span><br><span class="line"><span class="string">  function <span class="subst">$&#123;pluginname&#125;</span>_injector_config()&#123;</span></span><br><span class="line"><span class="string">    var parent_div_git = <span class="subst">$&#123;get_layout&#125;</span>;</span></span><br><span class="line"><span class="string">    var item_html = &#x27;<span class="subst">$&#123;temple_html_text&#125;</span>&#x27;;</span></span><br><span class="line"><span class="string">    console.log(&#x27;已挂载<span class="subst">$&#123;pluginname&#125;</span>&#x27;)</span></span><br><span class="line"><span class="string">    parent_div_git.insertAdjacentHTML(&quot;afterbegin&quot;,item_html)</span></span><br><span class="line"><span class="string">    &#125;</span></span><br><span class="line"><span class="string">  //屏蔽项判定</span></span><br><span class="line"><span class="string">  var elist = &#x27;<span class="subst">$&#123;data.exclude&#125;</span>&#x27;.split(&#x27;,&#x27;);</span></span><br><span class="line"><span class="string">  var cpage = location.pathname;</span></span><br><span class="line"><span class="string">  var epage = &#x27;<span class="subst">$&#123;data.enable_page&#125;</span>&#x27;;</span></span><br><span class="line"><span class="string">  var flag = 0; //标记值</span></span><br><span class="line"><span class="string">  //若命中屏蔽规则，则标记值加一</span></span><br><span class="line"><span class="string">  for (var i=0;i&lt;elist.length;i++)&#123;</span></span><br><span class="line"><span class="string">    if (cpage.includes(elist[i]))&#123;</span></span><br><span class="line"><span class="string">      flag++;</span></span><br><span class="line"><span class="string">    &#125;</span></span><br><span class="line"><span class="string">  &#125;</span></span><br><span class="line"><span class="string">  // 对全站生效时才会判断屏蔽项</span></span><br><span class="line"><span class="string">  if ((epage ===&#x27;all&#x27;)&amp;&amp;(flag == 0))&#123;</span></span><br><span class="line"><span class="string">    <span class="subst">$&#123;pluginname&#125;</span>_injector_config();</span></span><br><span class="line"><span class="string">  &#125;</span></span><br><span class="line"><span class="string">  // 对单一页面生效时无需判断屏蔽项</span></span><br><span class="line"><span class="string">  else if (epage === cpage)&#123;</span></span><br><span class="line"><span class="string">    <span class="subst">$&#123;pluginname&#125;</span>_injector_config();</span></span><br><span class="line"><span class="string">  &#125;</span></span><br><span class="line"><span class="string">  &lt;/script&gt;`</span></span><br><span class="line">  <span class="comment">// 使用hexo提供的注入器API，将对应的html代码片段注入到对应的位置</span></span><br><span class="line">  <span class="comment">// 此处利用挂载容器实现了二级注入，也就是所谓的套娃，</span></span><br><span class="line">  <span class="comment">// 注入用户脚本 将上文的容器脚本注入到body标签的结束符之前。</span></span><br><span class="line">  hexo.<span class="property">extend</span>.<span class="property">injector</span>.<span class="title function_">register</span>(<span class="string">&#x27;body_end&#x27;</span>, user_info_js, <span class="string">&quot;default&quot;</span>);</span><br><span class="line">  <span class="comment">// 注入脚本资源，将上文的容器脚本注入到body标签的结束符之前。</span></span><br><span class="line">  hexo.<span class="property">extend</span>.<span class="property">injector</span>.<span class="title function_">register</span>(<span class="string">&#x27;body_end&#x27;</span>, js_text, <span class="string">&quot;default&quot;</span>);</span><br><span class="line">  <span class="comment">// 注入样式资源，将上文的容器脚本注入到head标签的结束符之前。</span></span><br><span class="line">  hexo.<span class="property">extend</span>.<span class="property">injector</span>.<span class="title function_">register</span>(<span class="string">&#x27;head_end&#x27;</span>, css_text, <span class="string">&quot;default&quot;</span>);</span><br><span class="line">&#125;,</span><br><span class="line"><span class="comment">// 此处利用hexo提供的辅助函数来获取主题配置文件的配置内容，</span></span><br><span class="line"><span class="comment">// 如果不用辅助函数的话，最多只能读取到站点配置文件的内容。</span></span><br><span class="line">hexo.<span class="property">extend</span>.<span class="property">helper</span>.<span class="title function_">register</span>(<span class="string">&#x27;priority&#x27;</span>, <span class="keyword">function</span>(<span class="params"></span>)&#123;</span><br><span class="line">  <span class="comment">// 过滤器优先级，priority 值越低，过滤器会越早执行，默认priority是10</span></span><br><span class="line">  <span class="keyword">const</span> pre_priority = hexo.<span class="property">config</span>.<span class="property">config_name</span>.<span class="property">priority</span> || hexo.<span class="property">theme</span>.<span class="property">config</span>.<span class="property">config_name</span>.<span class="property">priority</span></span><br><span class="line">  <span class="comment">// 此处设置过滤器优先级的预设值</span></span><br><span class="line">  <span class="keyword">const</span> priority = pre_priority ? pre_priority : <span class="number">10</span></span><br><span class="line">  <span class="comment">// 返回最终的过滤器优先级数值</span></span><br><span class="line">  <span class="keyword">return</span> priority</span><br><span class="line">&#125;)</span><br><span class="line">)</span><br></pre></td></tr></table></figure></li></ul><button type="button" class="tab-to-top" aria-label="scroll to top"><i class="fas fa-arrow-up"></i></button></div><div class="tab-item-content" id="indexjs-2"><p>页面生成型的代码基本完全复用了由<a target="_blank" rel="noopener external nofollow noreferrer" href="https://github.com/jerryc127/butterfly-plugins">@butterfly主题作者jerry</a>开发的主题插件结构。以下仅做了具体注释。</p><ul><li>以页面生成型为例。首先是整体的文件目录结构<figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line">|__lib</span><br><span class="line">  |__html.pug  <span class="comment">#插件的主要dom结构</span></span><br><span class="line">  |__style.css <span class="comment">#可能用到的自定义样式</span></span><br><span class="line">  |__script.js <span class="comment">#可能用到的自定义脚本</span></span><br><span class="line">|__index.js</span><br><span class="line">|__package.json</span><br></pre></td></tr></table></figure></li><li>打开<code>index.js</code>,开始编写脚本。请详细阅读以下代码中的注释。我会尽量逐行解释。为了便于区分，我们约定不再变动的为常量，用<code>const</code>声明。会变动的为变量，用<code>let</code>或者<code>var</code>声明。（事实上在这个<code>index.js</code>中，<code>const</code>、<code>let</code>和<code>var</code>的生命周期没多大意义了。就算全部用<code>var</code>也没事）<br><div class="note info flat"><p>考虑到以下代码内容较多，建议复制到自己的编辑器内进行查看。您也可以将以下代码作为通用模板进行修改，来编写属于您自己的插件。</p></div><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">&#x27;use strict&#x27;</span></span><br><span class="line"><span class="comment">// 全局声明依赖，此处用到的都是hexo的api或者pug插件的api</span></span><br><span class="line"><span class="keyword">const</span> pug = <span class="built_in">require</span>(<span class="string">&#x27;pug&#x27;</span>)</span><br><span class="line"><span class="keyword">const</span> path = <span class="built_in">require</span>(<span class="string">&#x27;path&#x27;</span>)</span><br><span class="line"><span class="keyword">const</span> urlFor = <span class="built_in">require</span>(<span class="string">&#x27;hexo-util&#x27;</span>).<span class="property">url_for</span>.<span class="title function_">bind</span>(hexo)</span><br><span class="line"><span class="keyword">const</span> util = <span class="built_in">require</span>(<span class="string">&#x27;hexo-util&#x27;</span>)</span><br><span class="line"><span class="comment">// 调用hexo的生成器API</span></span><br><span class="line"><span class="comment">// 此处的pathname指生成的页面名称</span></span><br><span class="line">hexo.<span class="property">extend</span>.<span class="property">generator</span>.<span class="title function_">register</span>(<span class="string">&#x27;pathname&#x27;</span>, <span class="keyword">function</span> (<span class="params">locals</span>) &#123;</span><br><span class="line">  <span class="comment">// 首先获取整体的配置项名称,</span></span><br><span class="line">  <span class="comment">// 这行的写法可以保证不管是写在主题配置文件里</span></span><br><span class="line">  <span class="comment">// 还是站点配置文件里，都能读取到配置项。</span></span><br><span class="line">  <span class="keyword">const</span> config = hexo.<span class="property">config</span>.<span class="property">config_name</span> || hexo.<span class="property">theme</span>.<span class="property">config</span>.<span class="property">config_name</span></span><br><span class="line">  <span class="comment">// 如果配置开启</span></span><br><span class="line">  <span class="keyword">if</span> (!(config &amp;&amp; config.<span class="property">enable</span>)) <span class="keyword">return</span></span><br><span class="line">  <span class="comment">// 集体声明配置项，将我们用到的配置项全部封装到data里</span></span><br><span class="line">  <span class="comment">// 之后方便我们统一调用。</span></span><br><span class="line">  <span class="comment">// 同时活用三元运算符，给配置项设置默认配置内容。</span></span><br><span class="line">  <span class="keyword">const</span> data = &#123;</span><br><span class="line">    <span class="comment">//考虑到空页面没啥可参考的配置项，</span></span><br><span class="line">    <span class="comment">// 这里用hexo-butterfly-envelope的一些配置项作为写法示例</span></span><br><span class="line">    <span class="attr">author</span>: hexo.<span class="property">config</span>.<span class="property">author</span>,</span><br><span class="line">    <span class="attr">cover</span>: config.<span class="property">cover</span> ? <span class="title function_">urlFor</span>(config.<span class="property">cover</span>) : <span class="string">&quot;https://ae01.alicdn.com/kf/U5bb04af32be544c4b41206d9a42fcacfd.jpg&quot;</span>,</span><br><span class="line">    <span class="attr">message</span>: config.<span class="property">message</span> ?  config.<span class="property">message</span> : [<span class="string">&quot;有什么想问的？&quot;</span>,<span class="string">&quot;有什么想说的？&quot;</span>,<span class="string">&quot;有什么想吐槽的？&quot;</span>,<span class="string">&quot;哪怕是有什么想吃的，都可以告诉我哦~&quot;</span>],</span><br><span class="line">    <span class="attr">bottom</span>: config.<span class="property">bottom</span> ? config.<span class="property">bottom</span> : <span class="string">&quot;自动书记人偶竭诚为您服务&quot;</span>,</span><br><span class="line">    <span class="attr">height</span>: config.<span class="property">height</span> ? config.<span class="property">height</span> : <span class="string">&quot;1050px&quot;</span></span><br><span class="line">  &#125;</span><br><span class="line">  <span class="comment">// 渲染页面，此处调用了pug的api，具体写法可以查看最上方的参考教程。</span></span><br><span class="line">  <span class="keyword">const</span> content = pug.<span class="title function_">renderFile</span>(path.<span class="title function_">join</span>(__dirname, <span class="string">&#x27;./lib/html.pug&#x27;</span>), data)</span><br><span class="line">  <span class="comment">// 页面生成的访问路径</span></span><br><span class="line">  <span class="keyword">const</span> pathPre = config.<span class="property">path</span> || <span class="string">&#x27;pathname&#x27;</span></span><br><span class="line">  <span class="comment">// 获取主题默认生成页面的基本配置内容，样式。</span></span><br><span class="line">  <span class="keyword">let</span> pageDate = &#123;</span><br><span class="line">    <span class="attr">content</span>: content</span><br><span class="line">  &#125;</span><br><span class="line">  <span class="comment">// 获取页面的front_matter</span></span><br><span class="line">  <span class="keyword">if</span> (config.<span class="property">front_matter</span>) &#123;</span><br><span class="line">    pageDate = <span class="title class_">Object</span>.<span class="title function_">assign</span>(pageDate, config.<span class="property">front_matter</span>)</span><br><span class="line">  &#125;</span><br><span class="line"></span><br><span class="line">  <span class="keyword">return</span> &#123;</span><br><span class="line">    <span class="attr">path</span>: pathPre + <span class="string">&#x27;/index.html&#x27;</span>,</span><br><span class="line">    <span class="attr">data</span>: pageDate,</span><br><span class="line">    <span class="attr">layout</span>: [<span class="string">&#x27;page&#x27;</span>, <span class="string">&#x27;post&#x27;</span>]</span><br><span class="line">  &#125;</span><br><span class="line">&#125;)</span><br></pre></td></tr></table></figure></li></ul><button type="button" class="tab-to-top" aria-label="scroll to top"><i class="fas fa-arrow-up"></i></button></div></div></div></li><li>编写完毕以后我们就可以通过在插件文件夹根目录下执行<code>npm publish</code>指令来发布插件。</li><li>发布成功后，在hexo博客根目录<code>[Blogroot]</code>下运行安装插件指令安装你的插件。<figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">npm install package_name --save</span><br></pre></td></tr></table></figure></li><li>到主题配置文件<code>_config.butterfly.yml</code>或者<code>_config.yml</code>里添加配置项。运行<code>hexo cl &amp;&amp; hexo g &amp;&amp; hexo s</code>即可。</li><li>当然以上说的都是理想状态。一般我们都会遇到各种各样的报错。这时候我们不用着急去修改插件版本并重新发布、重新安装。可以直接在hexo博客的<code>[Blogroot]/node_modules</code>目录下找到我们的插件文件夹，然后在此处进行修改，并进行本地调试。等到在hexo博客处调整通过了。再将代码逐一复制到插件开发文件夹处。发布正式版本。</li></ol></div></details><h2 id="具体示例"><a href="#具体示例" class="headerlink" title="具体示例"></a>具体示例</h2><details class="folding-tag" cyan open><summary>点击折叠教程内容</summary><div class="content"><p>以<a target="_blank" rel="noopener external nofollow noreferrer" href="https://www.npmjs.com/package/hexo-butterfly-artitalk-pro">hexo-butterfly-artitalk-pro</a>为示例，这款插件结合了页面生成和侧栏插件注入的内容。源码公开在github。诸位开发者可以比对源码和上文的教程拆解以及下方的开发思路进行阅读。<br><a class="ghcard" rel="external nofollow noopener noreferrer noopener" target="_blank" href="https://github.com/akilarlxh/hexo-butterfly-artitalk-pro"><img class="no-lightbox" src="" data-lazy-src="https://github-readme-stats.vercel.app/api/pin/?username=akilarlxh&repo=hexo-butterfly-artitalk-pro&show_owner=true"></a></p><p>以下是我的开发流程。</p><ol><li>首先还是要先确定我们要用到的配置项。作为容器植入和页面生成并用的插件，自然要用到上文讨论的所有配置项。然后考虑到artitalk使用的api，还应该按照<a target="_blank" rel="noopener external nofollow noreferrer" href="https://artitalk.js.org">artitalk官方文档</a>设置必要配置项。再就是，若两种形式的插件并存，因为artitalk是根据id挂载的，势必需要一个屏蔽项<code>exclude</code>，确保页面版的时候不会加载侧栏版。于是得出我们的<span class="nota" data-nota="整体的开发过程是渐进式的，这里确定雏形是为了帮我们确立逻辑思维，毕竟后续再新增配置项也不是难事，即使是这里的配置项，我也是反复调整了不下五次的。">配置项雏形</span>。<figure class="highlight yml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br></pre></td><td class="code"><pre><span class="line"><span class="attr">artitalk:</span></span><br><span class="line">  <span class="attr">enable:</span></span><br><span class="line">    <span class="attr">card:</span> <span class="literal">true</span> <span class="comment"># 侧边栏开关</span></span><br><span class="line">    <span class="attr">page:</span> <span class="literal">true</span> <span class="comment">#页面开关</span></span><br><span class="line">  <span class="comment"># 侧栏相关配置项</span></span><br><span class="line">  <span class="attr">priority:</span> <span class="number">5</span> <span class="comment">#过滤器优先权</span></span><br><span class="line">  <span class="attr">enable_page:</span> <span class="string">all</span> <span class="comment"># 应用页面</span></span><br><span class="line">  <span class="attr">layout:</span> <span class="comment"># 挂载容器类型</span></span><br><span class="line">    <span class="attr">type:</span> <span class="string">class</span></span><br><span class="line">    <span class="attr">name:</span> <span class="string">sticky_layout</span></span><br><span class="line">    <span class="attr">index:</span> <span class="number">0</span></span><br><span class="line">  <span class="comment"># 页面相关配置项</span></span><br><span class="line">  <span class="attr">path:</span> <span class="string">artitalk</span></span><br><span class="line">  <span class="attr">front_matter:</span></span><br><span class="line">    <span class="attr">title:</span> <span class="string">碎碎念</span></span><br><span class="line">  <span class="comment"># 公共配置项</span></span><br><span class="line">  <span class="attr">appId:</span> <span class="string">***************************</span></span><br><span class="line">  <span class="attr">appKey:</span> <span class="string">****************************</span></span><br><span class="line">  <span class="attr">exclude:</span></span><br><span class="line">    <span class="bullet">-</span> <span class="string">/artitalk/</span></span><br><span class="line">  <span class="attr">js:</span> <span class="string">https://npm.elemecdn.com/artitalk</span></span><br><span class="line">  <span class="attr">option:</span></span><br></pre></td></tr></table></figure></li><li>确定文件目录树，这个保持之前的开发模式即可。<br><div class="note info flat"><p>此处我用到了<a target="_blank" rel="noopener external nofollow noreferrer" href="https://www.npmjs.com/package/stylus">stylus</a>作为css预编译语言。使用方法是全局安装stylus插件，然后使用它提供的指令将styl编译成css即可。<br></p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># 在本地全局安装stylus</span></span><br><span class="line">npm install stylus -g</span><br><span class="line"><span class="comment"># cd到.lib目录下</span></span><br><span class="line"><span class="built_in">cd</span> /.lib</span><br><span class="line"><span class="comment"># 使用stylus的编译指令进行编译</span></span><br><span class="line">stylus -w card.styl -o card.css</span><br></pre></td></tr></table></figure><p></p></div><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line">|__.lib</span><br><span class="line">  |__card_visual.js <span class="comment">#控制侧栏内容显隐的自定义脚本</span></span><br><span class="line">  |__card.css <span class="comment">#调整侧栏和页面适配的补丁样式表</span></span><br><span class="line">  |__card.styl <span class="comment">#预编译，主要是开发者本地使用</span></span><br><span class="line">  |__card.pug <span class="comment">#侧栏的dom结构</span></span><br><span class="line">  |__page.pug <span class="comment">#页面的dom结构</span></span><br><span class="line">|__index.js <span class="comment">#主要脚本，处理数据和控制插入</span></span><br><span class="line">|__package.json <span class="comment">#记录插件基本信息</span></span><br></pre></td></tr></table></figure></li><li>此处需要特别讲解的是<code>card.pug</code>和<code>page.pug</code>，我们需要注意它们在插件中的写法和在主题魔改源码时的写法的不同。主要表现在变量的获取写法。因为插件版的变量是在<code>index.js</code>就预先处理好的，所以可以直接调用。而源码魔改则是可以利用主题自带的一些辅助函数。考虑到多主题适配，显然插件版要摒弃对某一主题自带的辅助函数的依赖。<ul><li>card.pug<div class="tabs" id="cardpug-"><ul class="nav-tabs"><li class="tab"><button type="button" data-href="#cardpug--1">主题内魔改源码写法</button></li><li class="tab active"><button type="button" data-href="#cardpug--2">diff代码块表现修改内容</button></li><li class="tab"><button type="button" data-href="#cardpug--3">插件写法</button></li></ul><div class="tab-contents"><div class="tab-item-content" id="cardpug--1"><figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line">.card-widget.card-shuo</span><br><span class="line">  .card-content(style=&#x27;height:auto;min-height:280px;&#x27;)</span><br><span class="line">    .item-headline</span><br><span class="line">      i.fas.fa-comments</span><br><span class="line">      if theme.artitalk.page_enable</span><br><span class="line">        span</span><br><span class="line">          a(href=url_for(theme.artitalk.exclude) title=&quot;artitalk page link&quot;) 碎碎念</span><br><span class="line">      else</span><br><span class="line">        span 碎碎念</span><br><span class="line">      a#cardVisual(style=&#x27;cursor:pointer;float:right&#x27;  onclick=&#x27;cardVisual()&#x27;) 编辑</span><br><span class="line">    #artitalk_main(style=&#x27;width:100%;height:100%;padding:1px&#x27;)</span><br></pre></td></tr></table></figure><button type="button" class="tab-to-top" aria-label="scroll to top"><i class="fas fa-arrow-up"></i></button></div><div class="tab-item-content active" id="cardpug--2"><figure class="highlight diff"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre></td><td class="code"><pre><span class="line">  .card-widget.card-shuo</span><br><span class="line">    .card-content(style=&#x27;height:auto;min-height:280px;&#x27;)</span><br><span class="line">      .item-headline</span><br><span class="line">        i.fas.fa-comments</span><br><span class="line"><span class="deletion">-       if theme.artitalk.page_enable</span></span><br><span class="line"><span class="addition">+       if page_enable</span></span><br><span class="line">          span</span><br><span class="line"><span class="deletion">-           a(href=url_for(theme.artitalk.exclude) title=&quot;artitalk page link&quot;) 碎碎念</span></span><br><span class="line"><span class="addition">+           a(href=exclude title=&quot;artitalk page link&quot;) 碎碎念</span></span><br><span class="line">        else</span><br><span class="line">          span 碎碎念</span><br><span class="line">        a#cardVisual(style=&#x27;cursor:pointer;float:right&#x27;  onclick=&#x27;cardVisual()&#x27;) 编辑</span><br><span class="line">      #artitalk_main(style=&#x27;width:100%;height:100%;padding:1px&#x27;)</span><br></pre></td></tr></table></figure><button type="button" class="tab-to-top" aria-label="scroll to top"><i class="fas fa-arrow-up"></i></button></div><div class="tab-item-content" id="cardpug--3"><figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line">.card-widget.card-shuo</span><br><span class="line">  .card-content(style=&#x27;height:auto;min-height:280px;&#x27;)</span><br><span class="line">    .item-headline</span><br><span class="line">      i.fas.fa-comments</span><br><span class="line">      if page_enable</span><br><span class="line">        span</span><br><span class="line">          a(href=exclude title=&quot;artitalk page link&quot;) 碎碎念</span><br><span class="line">      else</span><br><span class="line">        span 碎碎念</span><br><span class="line">      a#cardVisual(style=&#x27;cursor:pointer;float:right&#x27;  onclick=&#x27;cardVisual()&#x27;) 编辑</span><br><span class="line">    #artitalk_main(style=&#x27;width:100%;height:100%;padding:1px&#x27;)</span><br></pre></td></tr></table></figure><button type="button" class="tab-to-top" aria-label="scroll to top"><i class="fas fa-arrow-up"></i></button></div></div></div></li><li>page.pug<div class="tabs" id="cardpug-"><ul class="nav-tabs"><li class="tab"><button type="button" data-href="#cardpug--1">主题内魔改源码写法</button></li><li class="tab active"><button type="button" data-href="#cardpug--2">diff代码块表现修改内容</button></li><li class="tab"><button type="button" data-href="#cardpug--3">插件写法</button></li></ul><div class="tab-contents"><div class="tab-item-content" id="cardpug--1"><figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br></pre></td><td class="code"><pre><span class="line">#artitalk_main</span><br><span class="line">  .js-pjax</span><br><span class="line">    script.</span><br><span class="line">      (()=&gt;&#123;</span><br><span class="line">        const init = () =&gt; &#123;</span><br><span class="line">          new Artitalk(Object.assign(&#123;</span><br><span class="line">            appId: &#x27;!&#123;theme.artitalk.appId&#125;&#x27;,</span><br><span class="line">            appKey: &#x27;!&#123;theme.artitalk.appKey&#125;&#x27;,</span><br><span class="line">          &#125;, !&#123;theme.artitalk.option&#125; ))</span><br><span class="line">        &#125;</span><br><span class="line"></span><br><span class="line">        if (typeof Artitalk === &#x27;function&#x27;) &#123;</span><br><span class="line">          init()</span><br><span class="line">        &#125; else &#123;</span><br><span class="line">          getScript(&#x27;!&#123;theme.CDN.artitalk&#125;&#x27;).then(init)</span><br><span class="line">        &#125;</span><br><span class="line">      &#125;)()</span><br></pre></td></tr></table></figure><button type="button" class="tab-to-top" aria-label="scroll to top"><i class="fas fa-arrow-up"></i></button></div><div class="tab-item-content active" id="cardpug--2"><figure class="highlight diff"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br></pre></td><td class="code"><pre><span class="line">  #artitalk_main</span><br><span class="line">    .js-pjax</span><br><span class="line">      script.</span><br><span class="line">        (()=&gt;&#123;</span><br><span class="line">          const init = () =&gt; &#123;</span><br><span class="line">            new Artitalk(Object.assign(&#123;</span><br><span class="line"><span class="deletion">-             appId: &#x27;!&#123;theme.artitalk.appId&#125;&#x27;,</span></span><br><span class="line"><span class="deletion">-             appKey: &#x27;!&#123;theme.artitalk.appKey&#125;&#x27;,</span></span><br><span class="line"><span class="deletion">-           &#125;, !&#123;theme.artitalk.option&#125; ))</span></span><br><span class="line"><span class="addition">+             appId: &#x27;#&#123;appId&#125;&#x27;,</span></span><br><span class="line"><span class="addition">+             appKey: &#x27;#&#123;appKey&#125;&#x27;,</span></span><br><span class="line"><span class="addition">+           &#125;, !&#123;option&#125; ))</span></span><br><span class="line">          &#125;</span><br><span class="line"></span><br><span class="line">          if (typeof Artitalk <span class="comment">=== &#x27;function&#x27;) &#123;</span></span><br><span class="line">            init()</span><br><span class="line">          &#125; else &#123;</span><br><span class="line"><span class="deletion">-           getScript(&#x27;!&#123;theme.CDN.artitalk&#125;&#x27;).then(init)</span></span><br><span class="line"><span class="addition">+           getScript(&#x27;!&#123;js&#125;&#x27;).then(init)</span></span><br><span class="line">          &#125;</span><br><span class="line">        &#125;)()</span><br></pre></td></tr></table></figure><button type="button" class="tab-to-top" aria-label="scroll to top"><i class="fas fa-arrow-up"></i></button></div><div class="tab-item-content" id="cardpug--3"><figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br></pre></td><td class="code"><pre><span class="line">#artitalk_main</span><br><span class="line">.js-pjax</span><br><span class="line">  script.</span><br><span class="line">    (()=&gt;&#123;</span><br><span class="line">      const init = () =&gt; &#123;</span><br><span class="line">        new Artitalk(Object.assign(&#123;</span><br><span class="line">          appId: &#x27;#&#123;appId&#125;&#x27;,</span><br><span class="line">          appKey: &#x27;#&#123;appKey&#125;&#x27;,</span><br><span class="line">        &#125;, !&#123;option&#125; ))</span><br><span class="line">      &#125;</span><br><span class="line"></span><br><span class="line">      if (typeof Artitalk === &#x27;function&#x27;) &#123;</span><br><span class="line">        init()</span><br><span class="line">      &#125; else &#123;</span><br><span class="line">        getScript(&#x27;!&#123;js&#125;&#x27;).then(init)</span><br><span class="line">      &#125;</span><br><span class="line">    &#125;)()</span><br></pre></td></tr></table></figure><button type="button" class="tab-to-top" aria-label="scroll to top"><i class="fas fa-arrow-up"></i></button></div></div></div></li></ul></li><li>然后就是关键的<code>index.js</code>了。<br><div class="note info flat"><p>考虑到以下代码内容较多，建议复制到自己的编辑器内进行查看。您也可以将以下代码作为通用模板进行修改，来编写属于您自己的插件。</p></div><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br><span class="line">83</span><br><span class="line">84</span><br><span class="line">85</span><br><span class="line">86</span><br><span class="line">87</span><br><span class="line">88</span><br><span class="line">89</span><br><span class="line">90</span><br><span class="line">91</span><br><span class="line">92</span><br><span class="line">93</span><br><span class="line">94</span><br><span class="line">95</span><br><span class="line">96</span><br><span class="line">97</span><br><span class="line">98</span><br><span class="line">99</span><br><span class="line">100</span><br><span class="line">101</span><br><span class="line">102</span><br><span class="line">103</span><br><span class="line">104</span><br><span class="line">105</span><br><span class="line">106</span><br><span class="line">107</span><br><span class="line">108</span><br><span class="line">109</span><br><span class="line">110</span><br><span class="line">111</span><br><span class="line">112</span><br><span class="line">113</span><br><span class="line">114</span><br><span class="line">115</span><br><span class="line">116</span><br><span class="line">117</span><br><span class="line">118</span><br><span class="line">119</span><br><span class="line">120</span><br><span class="line">121</span><br><span class="line">122</span><br><span class="line">123</span><br><span class="line">124</span><br><span class="line">125</span><br><span class="line">126</span><br><span class="line">127</span><br><span class="line">128</span><br><span class="line">129</span><br><span class="line">130</span><br><span class="line">131</span><br><span class="line">132</span><br><span class="line">133</span><br><span class="line">134</span><br><span class="line">135</span><br><span class="line">136</span><br><span class="line">137</span><br><span class="line">138</span><br><span class="line">139</span><br><span class="line">140</span><br><span class="line">141</span><br><span class="line">142</span><br><span class="line">143</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">&#x27;use strict&#x27;</span></span><br><span class="line"><span class="comment">// 全局声明侧栏插件代号</span></span><br><span class="line"><span class="keyword">const</span> pluginname = <span class="string">&#x27;card_artitalk&#x27;</span></span><br><span class="line"><span class="comment">// 全局声明依赖</span></span><br><span class="line"><span class="keyword">const</span> pug = <span class="built_in">require</span>(<span class="string">&#x27;pug&#x27;</span>)</span><br><span class="line"><span class="keyword">const</span> path = <span class="built_in">require</span>(<span class="string">&#x27;path&#x27;</span>)</span><br><span class="line"><span class="keyword">const</span> urlFor = <span class="built_in">require</span>(<span class="string">&#x27;hexo-util&#x27;</span>).<span class="property">url_for</span>.<span class="title function_">bind</span>(hexo)</span><br><span class="line"><span class="keyword">const</span> util = <span class="built_in">require</span>(<span class="string">&#x27;hexo-util&#x27;</span>)</span><br><span class="line"></span><br><span class="line"><span class="comment">// 先来编写侧栏插件，使用容器注入式开发模板</span></span><br><span class="line"></span><br><span class="line">hexo.<span class="property">extend</span>.<span class="property">filter</span>.<span class="title function_">register</span>(<span class="string">&#x27;after_generate&#x27;</span>, <span class="keyword">function</span> (<span class="params">locals</span>) &#123;</span><br><span class="line">  <span class="comment">// 首先获取整体的配置项名称</span></span><br><span class="line">  <span class="keyword">const</span> config = hexo.<span class="property">config</span>.<span class="property">artitalk</span> || hexo.<span class="property">theme</span>.<span class="property">config</span>.<span class="property">artitalk</span></span><br><span class="line">  <span class="comment">// 如果配置开启</span></span><br><span class="line">  <span class="keyword">if</span> (!(config &amp;&amp; config.<span class="property">enable</span>.<span class="property">card</span>)) <span class="keyword">return</span></span><br><span class="line">  <span class="comment">// 集体声明配置项</span></span><br><span class="line">    <span class="keyword">const</span> card_data = &#123;</span><br><span class="line">      <span class="attr">page_enable</span>: config.<span class="property">enable</span>.<span class="property">page</span> ? config.<span class="property">enable</span>.<span class="property">page</span> : <span class="literal">false</span>,</span><br><span class="line">      <span class="attr">enable_page</span>: config.<span class="property">enable_page</span> ? config.<span class="property">enable_page</span> : <span class="string">&quot;all&quot;</span>,</span><br><span class="line">      <span class="attr">layout_type</span>: config.<span class="property">layout</span>.<span class="property">type</span>,</span><br><span class="line">      <span class="attr">layout_name</span>: config.<span class="property">layout</span>.<span class="property">name</span>,</span><br><span class="line">      <span class="attr">layout_index</span>: config.<span class="property">layout</span>.<span class="property">index</span> ? config.<span class="property">layout</span>.<span class="property">index</span> : <span class="number">0</span>,</span><br><span class="line">      <span class="attr">path</span>: config.<span class="property">path</span> ? config.<span class="property">path</span> : <span class="string">&quot;artitalk&quot;</span>,</span><br><span class="line">      <span class="attr">exclude</span>: config.<span class="property">exclude</span> ? config.<span class="property">exclude</span> : <span class="string">&quot;/artitalk/&quot;</span>,</span><br><span class="line">      <span class="attr">appId</span>: config.<span class="property">appId</span>,</span><br><span class="line">      <span class="attr">appKey</span>: config.<span class="property">appKey</span>,</span><br><span class="line">      <span class="attr">option</span>: config.<span class="property">option</span> ? <span class="title class_">JSON</span>.<span class="title function_">stringify</span>(config.<span class="property">option</span>) : <span class="literal">false</span>,</span><br><span class="line">      <span class="attr">js</span>: config.<span class="property">js</span> ? <span class="title function_">urlFor</span>(config.<span class="property">js</span>) : <span class="string">&#x27;https://npm.elemecdn.com/artitalk&#x27;</span></span><br><span class="line">    &#125;</span><br><span class="line">  <span class="comment">// 渲染页面</span></span><br><span class="line">  <span class="keyword">const</span> temple_html_text = config.<span class="property">temple_html</span> ? config.<span class="property">temple_html</span> : pug.<span class="title function_">renderFile</span>(path.<span class="title function_">join</span>(__dirname, <span class="string">&#x27;./lib/card.pug&#x27;</span>),card_data)</span><br><span class="line"></span><br><span class="line">  <span class="comment">//cdn资源声明</span></span><br><span class="line">    <span class="comment">//样式资源</span></span><br><span class="line">  <span class="keyword">const</span> css_text = <span class="string">`&lt;link rel=&quot;stylesheet&quot; href=&quot;https://npm.elemecdn.com/hexo-butterfly-artitalk-pro/lib/card.css&quot; media=&quot;defer&quot; onload=&quot;this.media=&#x27;all&#x27;&quot;&gt;`</span></span><br><span class="line">    <span class="comment">//脚本资源</span></span><br><span class="line">  <span class="keyword">const</span> js_text = <span class="string">`&lt;script async src=&quot;https://npm.elemecdn.com/hexo-butterfly-artitalk-pro/lib/card_visual.js&quot;&gt;&lt;/script&gt;`</span></span><br><span class="line"></span><br><span class="line">  <span class="comment">//注入容器声明</span></span><br><span class="line">  <span class="keyword">var</span> get_layout</span><br><span class="line">  <span class="comment">//若指定为class类型的容器</span></span><br><span class="line">  <span class="keyword">if</span> (card_data.<span class="property">layout_type</span> === <span class="string">&#x27;class&#x27;</span>) &#123;</span><br><span class="line">    <span class="comment">//则根据class类名及序列获取容器</span></span><br><span class="line">    get_layout = <span class="string">`document.getElementsByClassName(&#x27;<span class="subst">$&#123;card_data.layout_name&#125;</span>&#x27;)[<span class="subst">$&#123;card_data.layout_index&#125;</span>]`</span></span><br><span class="line">  &#125;</span><br><span class="line">  <span class="comment">// 若指定为id类型的容器</span></span><br><span class="line">  <span class="keyword">else</span> <span class="keyword">if</span> (card_data.<span class="property">layout_type</span> === <span class="string">&#x27;id&#x27;</span>) &#123;</span><br><span class="line">    <span class="comment">// 直接根据id获取容器</span></span><br><span class="line">    get_layout = <span class="string">`document.getElementById(&#x27;<span class="subst">$&#123;card_data.layout_name&#125;</span>&#x27;)`</span></span><br><span class="line">  &#125;</span><br><span class="line">  <span class="comment">// 若未指定容器类型，默认使用id查询</span></span><br><span class="line">  <span class="keyword">else</span> &#123;</span><br><span class="line">    get_layout = <span class="string">`document.getElementById(&#x27;<span class="subst">$&#123;card_data.layout_name&#125;</span>&#x27;)`</span></span><br><span class="line">  &#125;</span><br><span class="line">  <span class="comment">// 挂载容器脚本</span></span><br><span class="line">  <span class="comment">// 此处还在挂载脚本后面附上了artitalk初始化函数。</span></span><br><span class="line">  <span class="keyword">var</span> user_info_js = <span class="string">`&lt;script data-pjax&gt;</span></span><br><span class="line"><span class="string">  function <span class="subst">$&#123;pluginname&#125;</span>_injector_config()&#123;</span></span><br><span class="line"><span class="string">    var parent_div_git = <span class="subst">$&#123;get_layout&#125;</span>;</span></span><br><span class="line"><span class="string">    var item_html = &#x27;<span class="subst">$&#123;temple_html_text&#125;</span>&#x27;;</span></span><br><span class="line"><span class="string">    console.log(&#x27;已挂载<span class="subst">$&#123;pluginname&#125;</span>&#x27;);</span></span><br><span class="line"><span class="string">    parent_div_git.insertAdjacentHTML(&quot;afterbegin&quot;,item_html);</span></span><br><span class="line"><span class="string">    (()=&gt;&#123;</span></span><br><span class="line"><span class="string">      const init = () =&gt; &#123;</span></span><br><span class="line"><span class="string">        new Artitalk(Object.assign(&#123;</span></span><br><span class="line"><span class="string">          appId: &#x27;<span class="subst">$&#123;card_data.appId&#125;</span>&#x27;,</span></span><br><span class="line"><span class="string">          appKey: &#x27;<span class="subst">$&#123;card_data.appKey&#125;</span>&#x27;,</span></span><br><span class="line"><span class="string">        &#125;, <span class="subst">$&#123;card_data.option&#125;</span> ))</span></span><br><span class="line"><span class="string">      &#125;</span></span><br><span class="line"><span class="string">      if (typeof Artitalk === &#x27;function&#x27;) &#123;</span></span><br><span class="line"><span class="string">        init()</span></span><br><span class="line"><span class="string">      &#125; else &#123;</span></span><br><span class="line"><span class="string">        getScript(&#x27;<span class="subst">$&#123;card_data.js&#125;</span>&#x27;).then(init)</span></span><br><span class="line"><span class="string">      &#125;</span></span><br><span class="line"><span class="string">    &#125;)()</span></span><br><span class="line"><span class="string">    &#125;</span></span><br><span class="line"><span class="string">  var elist = &#x27;<span class="subst">$&#123;card_data.exclude&#125;</span>&#x27;.split(&#x27;,&#x27;);</span></span><br><span class="line"><span class="string">  var cpage = location.pathname;</span></span><br><span class="line"><span class="string">  var epage = &#x27;<span class="subst">$&#123;card_data.enable_page&#125;</span>&#x27;;</span></span><br><span class="line"><span class="string">  var flag = 0;</span></span><br><span class="line"><span class="string"></span></span><br><span class="line"><span class="string">  for (var i=0;i&lt;elist.length;i++)&#123;</span></span><br><span class="line"><span class="string">    if (cpage.includes(elist[i]))&#123;</span></span><br><span class="line"><span class="string">      flag++;</span></span><br><span class="line"><span class="string">    &#125;</span></span><br><span class="line"><span class="string">  &#125;</span></span><br><span class="line"><span class="string"></span></span><br><span class="line"><span class="string">  if ((epage ===&#x27;all&#x27;)&amp;&amp;(flag == 0))&#123;</span></span><br><span class="line"><span class="string">    <span class="subst">$&#123;pluginname&#125;</span>_injector_config();</span></span><br><span class="line"><span class="string">  &#125;</span></span><br><span class="line"><span class="string">  else if (epage === cpage)&#123;</span></span><br><span class="line"><span class="string">    <span class="subst">$&#123;pluginname&#125;</span>_injector_config();</span></span><br><span class="line"><span class="string">  &#125;</span></span><br><span class="line"><span class="string">  &lt;/script&gt;`</span></span><br><span class="line">  <span class="comment">// 注入用户脚本</span></span><br><span class="line">  <span class="comment">// 此处利用挂载容器实现了二级注入</span></span><br><span class="line">  hexo.<span class="property">extend</span>.<span class="property">injector</span>.<span class="title function_">register</span>(<span class="string">&#x27;body_end&#x27;</span>, user_info_js, <span class="string">&quot;default&quot;</span>);</span><br><span class="line">  <span class="comment">// 注入脚本资源</span></span><br><span class="line">  hexo.<span class="property">extend</span>.<span class="property">injector</span>.<span class="title function_">register</span>(<span class="string">&#x27;body_end&#x27;</span>, js_text, <span class="string">&quot;default&quot;</span>);</span><br><span class="line">  <span class="comment">// 注入样式资源</span></span><br><span class="line">  hexo.<span class="property">extend</span>.<span class="property">injector</span>.<span class="title function_">register</span>(<span class="string">&#x27;head_end&#x27;</span>, css_text, <span class="string">&quot;default&quot;</span>);</span><br><span class="line">&#125;,</span><br><span class="line">hexo.<span class="property">extend</span>.<span class="property">helper</span>.<span class="title function_">register</span>(<span class="string">&#x27;priority&#x27;</span>, <span class="keyword">function</span>(<span class="params"></span>)&#123;</span><br><span class="line">  <span class="comment">// 过滤器优先级，priority 值越低，过滤器会越早执行，默认priority是10</span></span><br><span class="line">  <span class="keyword">const</span> pre_priority = hexo.<span class="property">config</span>.<span class="property">artitalk</span>.<span class="property">priority</span> || hexo.<span class="property">theme</span>.<span class="property">config</span>.<span class="property">artitalk</span>.<span class="property">priority</span></span><br><span class="line">  <span class="keyword">const</span> priority = pre_priority ? pre_priority : <span class="number">10</span></span><br><span class="line">  <span class="keyword">return</span> priority</span><br><span class="line">&#125;)</span><br><span class="line">)</span><br><span class="line"></span><br><span class="line"><span class="comment">// 再是编写页面版插件，使用页面生成式模板</span></span><br><span class="line"><span class="comment">// 此处直接复用hexo-butterfly-artitalk的原代码</span></span><br><span class="line">hexo.<span class="property">extend</span>.<span class="property">generator</span>.<span class="title function_">register</span>(<span class="string">&#x27;artitalk&#x27;</span>, <span class="keyword">function</span> (<span class="params">locals</span>) &#123;</span><br><span class="line">  <span class="keyword">const</span> config = hexo.<span class="property">config</span>.<span class="property">artitalk</span> || hexo.<span class="property">theme</span>.<span class="property">config</span>.<span class="property">artitalk</span></span><br><span class="line"></span><br><span class="line">  <span class="keyword">if</span> (!(config &amp;&amp; config.<span class="property">enable</span>.<span class="property">page</span>)) <span class="keyword">return</span></span><br><span class="line"></span><br><span class="line">  <span class="keyword">const</span> page_data = &#123;</span><br><span class="line">    <span class="attr">appId</span>: config.<span class="property">appId</span>,</span><br><span class="line">    <span class="attr">appKey</span>: config.<span class="property">appKey</span>,</span><br><span class="line">    <span class="attr">option</span>: config.<span class="property">option</span> ? <span class="title class_">JSON</span>.<span class="title function_">stringify</span>(config.<span class="property">option</span>) : <span class="literal">false</span>,</span><br><span class="line">    <span class="attr">js</span>: config.<span class="property">js</span> ? <span class="title function_">urlFor</span>(config.<span class="property">js</span>) : <span class="string">&#x27;https://npm.elemecdn.com/artitalk&#x27;</span></span><br><span class="line">  &#125;</span><br><span class="line"></span><br><span class="line">  <span class="keyword">const</span> content = pug.<span class="title function_">renderFile</span>(path.<span class="title function_">join</span>(__dirname, <span class="string">&#x27;./lib/page.pug&#x27;</span>), page_data)</span><br><span class="line"></span><br><span class="line">  <span class="keyword">const</span> pathPre = config.<span class="property">path</span> || <span class="string">&#x27;artitalk&#x27;</span></span><br><span class="line"></span><br><span class="line">  <span class="keyword">let</span> pageDate = &#123;</span><br><span class="line">    <span class="attr">content</span>: content</span><br><span class="line">  &#125;</span><br><span class="line"></span><br><span class="line">  <span class="keyword">if</span> (config.<span class="property">front_matter</span>) &#123;</span><br><span class="line">    pageDate = <span class="title class_">Object</span>.<span class="title function_">assign</span>(pageDate, config.<span class="property">front_matter</span>)</span><br><span class="line">  &#125;</span><br><span class="line"></span><br><span class="line">  <span class="keyword">return</span> &#123;</span><br><span class="line">    <span class="attr">path</span>: pathPre + <span class="string">&#x27;/index.html&#x27;</span>,</span><br><span class="line">    <span class="attr">data</span>: pageDate,</span><br><span class="line">    <span class="attr">layout</span>: [<span class="string">&#x27;page&#x27;</span>, <span class="string">&#x27;post&#x27;</span>]</span><br><span class="line">  &#125;</span><br><span class="line">&#125;)</span><br></pre></td></tr></table></figure></li><li>之后通过<code>npm publish</code>发布即可。不过个人建议不要忘记编写<code>README.md</code>，从我个人的开发经验来看，后续维护的时候，这个文档会很好的帮到自己。</li></ol></div></details><h2 id="更多已开发插件"><a href="#更多已开发插件" class="headerlink" title="更多已开发插件"></a>更多已开发插件</h2><p>以下是一些已经完成的插件源码。权且作为参考。开发模式基本同本帖所讨论的模板方案。在涉及一些辅助函数的时候也有详细注释。各位开发者可以选择适当的内容作为参照。</p><div class="table-container"><table><thead><tr><th style="text-align:left">插件仓库</th><th style="text-align:left">类型</th><th style="text-align:left">参考方向推荐</th></tr></thead><tbody><tr><td style="text-align:left"><a class="ghcard" rel="external nofollow noopener noreferrer noopener" target="_blank" href="https://github.com/akilarlxh/hexo-butterfly-artitalk-pro"><img class="no-lightbox" src="" data-lazy-src="https://github-readme-stats.vercel.app/api/pin/?username=akilarlxh&repo=hexo-butterfly-artitalk-pro&show_owner=true"></a></td><td style="text-align:left">容器植入式、页面生成式</td><td style="text-align:left">侧栏魔改方案插件化，页面生成方案插件化，初始化脚本动态生成。</td></tr><tr><td style="text-align:left"><a class="ghcard" rel="external nofollow noopener noreferrer noopener" target="_blank" href="https://github.com/akilarlxh/hexo-butterfly-clock"><img class="no-lightbox" src="" data-lazy-src="https://github-readme-stats.vercel.app/api/pin/?username=akilarlxh&repo=hexo-butterfly-clock&show_owner=true"></a></td><td style="text-align:left">容器植入式</td><td style="text-align:left">侧栏魔改方案插件化</td></tr><tr><td style="text-align:left"><a class="ghcard" rel="external nofollow noopener noreferrer noopener" target="_blank" href="https://github.com/akilarlxh/hexo-butterfly-wowjs"><img class="no-lightbox" src="" data-lazy-src="https://github-readme-stats.vercel.app/api/pin/?username=akilarlxh&repo=hexo-butterfly-wowjs&show_owner=true"></a></td><td style="text-align:left">容器植入式</td><td style="text-align:left">依赖添加，补丁添加，通过配置项给页面dom动态添加class，外挂标签插件植入</td></tr><tr><td style="text-align:left"><a class="ghcard" rel="external nofollow noopener noreferrer noopener" target="_blank" href="https://github.com/akilarlxh/hexo-butterfly-envelope"><img class="no-lightbox" src="" data-lazy-src="https://github-readme-stats.vercel.app/api/pin/?username=akilarlxh&repo=hexo-butterfly-envelope&show_owner=true"></a></td><td style="text-align:left">页面生成式</td><td style="text-align:left">单独页面生成模板。动态生成css</td></tr><tr><td style="text-align:left"><a class="ghcard" rel="external nofollow noopener noreferrer noopener" target="_blank" href="https://github.com/akilarlxh/hexo-butterfly-fcircle"><img class="no-lightbox" src="" data-lazy-src="https://github-readme-stats.vercel.app/api/pin/?username=akilarlxh&repo=hexo-butterfly-fcircle&show_owner=true"></a></td><td style="text-align:left">页面生成式</td><td style="text-align:left">单独页面生成模板</td></tr><tr><td style="text-align:left"><a class="ghcard" rel="external nofollow noopener noreferrer noopener" target="_blank" href="https://github.com/akilarlxh/hexo-butterfly-swiper"><img class="no-lightbox" src="" data-lazy-src="https://github-readme-stats.vercel.app/api/pin/?username=akilarlxh&repo=hexo-butterfly-swiper&show_owner=true"></a></td><td style="text-align:left">容器植入式</td><td style="text-align:left">结合文章front-matter进行筛选，实现与post的front-matter联动</td></tr><tr><td style="text-align:left"><a class="ghcard" rel="external nofollow noopener noreferrer noopener" target="_blank" href="https://github.com/akilarlxh/hexo-filter-gitcalendar"><img class="no-lightbox" src="" data-lazy-src="https://github-readme-stats.vercel.app/api/pin/?username=akilarlxh&repo=hexo-filter-gitcalendar&show_owner=true"></a></td><td style="text-align:left">容器植入式</td><td style="text-align:left">多主题适配，读取主题，自动加载容器</td></tr></tbody></table></div><h2 id="TO-DO"><a href="#TO-DO" class="headerlink" title="TO DO"></a>TO DO</h2><div class="checkbox blue checked"><input type="checkbox" checked><p>讲解可能用到的一些api</p></div><div class="checkbox blue checked"><input type="checkbox" checked><p>具体案例</p></div><div class="checkbox blue checked"><input type="checkbox" checked><p>已开发插件源码示例</p></div></article><div class="post-copyright"><div class="post-copyright__title"><span class="post-copyright-info"><h>NPM插件的开发</h></span></div><div class="post-copyright__type"><span class="post-copyright-info"><a href="https://akilar.top/posts/e44fb560/">https://akilar.top/posts/e44fb560/</a></span></div><div class="post-copyright-m"><div class="post-copyright-m-info"><div class="post-copyright-a"><h>作者</h><div class="post-copyright-cc-info"><h>Akilar</h></div></div><div class="post-copyright-c"><h>发布于</h><div class="post-copyright-cc-info"><h>2021-06-30</h></div></div><div class="post-copyright-u"><h>更新于</h><div class="post-copyright-cc-info"><h>2021-06-30</h></div></div><div class="post-copyright-c"><h>许可协议</h><div class="post-copyright-cc-info"><a class="icon" rel="noopener external nofollow noreferrer" target="_blank" title="Creative Commons" href="https://creativecommons.org/"><i class="fab fa-creative-commons"></i></a><a rel="noopener external nofollow noreferrer" target="_blank" title="CC BY-NC-SA 4.0" href="https://creativecommons.org/licenses/by-nc-sa/4.0/">CC BY-NC-SA 4.0</a></div></div></div></div></div><div class="tag_share"><div class="post-meta__tag-list"><a class="post-meta__tags" href="/tags/%F0%9F%8C%8C%E7%B3%96%E6%9E%9C%E5%B1%8B%E3%81%AE%E4%B8%80%E5%8D%83%E9%9B%B6%E4%B8%80%E5%A4%9C/">🌌糖果屋の一千零一夜</a><a class="post-meta__tags" href="/tags/%F0%9F%94%A9NPM%E6%8F%92%E4%BB%B6%E5%BC%80%E5%8F%91/">🔩NPM插件开发</a></div><div class="post_share"></div></div><link rel="stylesheet" href="https://npm.elemecdn.com/akiblog@1.0.1/css/coin.css" media="defer" onload='this.media="all"'><div class="post-reward"><button class="tip-button reward-button"><span class="tip-button__text">不给糖果就捣蛋</span><div class="coin-wrapper"><div class="coin"><div class="coin__middle"></div><div class="coin__back"></div><div class="coin__front"></div></div></div><div class="reward-main"><ul class="reward-all"><li class="reward-item"><a href="https://npm.elemecdn.com/akiblog@1.0.1/img/wechat.png" rel="external nofollow noreferrer" target="_blank"><img class="post-qr-code-img" src="" data-lazy-src="https://npm.elemecdn.com/akiblog@1.0.1/img/wechat.png" alt="wechat"></a><div class="post-qr-code-desc">wechat</div></li><li class="reward-item"><a href="https://npm.elemecdn.com/akiblog@1.0.1/img/alipay.png" rel="external nofollow noreferrer" target="_blank"><img class="post-qr-code-img" src="" data-lazy-src="https://npm.elemecdn.com/akiblog@1.0.1/img/alipay.png" alt="alipay"></a><div class="post-qr-code-desc">alipay</div></li></ul></div></button></div><audio id="coinAudio" src="https://npm.elemecdn.com/akilar-candyassets/audio/aowu.m4a"></audio><script defer src="https://npm.elemecdn.com/akiblog@1.0.1/js/custom/coin.js"></script><nav class="pagination-post" id="pagination"><div class="prev-post pull-left"><a href="javascript:void(0);" rel="external nofollow noreferrer" onclick="SAONotify(&quot;Prev Post&quot;,&quot;是否跳转至上一篇：&lt;br&gt;工信部举报腾讯的正确姿势&quot;,&quot;pjax.loadUrl('/posts/b5324e2c/')&quot;)" title="工信部举报腾讯的正确姿势"><i class="fas fa-chevron-left prev-icon"><div class="prev-label">上一篇</div></i></a><div class="pagination-card"><img class="prev-cover" src="" data-lazy-src="https://npm.elemecdn.com/akilar-candyassets/image/0589a0cc.png" onerror='onerror=null,src="https://npm.elemecdn.com/akiblog@1.0.1/img/loading.gif"' alt="cover of previous post"><div class="pagination-info"><div class="label">上一篇</div><div class="prev_info">工信部举报腾讯的正确姿势</div></div></div></div><div class="next-post pull-right"><a href="javascript:void(0);" rel="external nofollow noreferrer" onclick="SAONotify(&quot;Next Post&quot;,&quot;是否跳转至下一篇：&lt;br&gt;7月15日 星期四 晴&quot;,&quot;pjax.loadUrl('/posts/8b514f19/')&quot;)" title="7月15日 星期四 晴"><i class="fas fa-chevron-right next-icon"><div class="next-label">下一篇</div></i></a><div class="pagination-card"><img class="next-cover" src="" data-lazy-src="https://img.zcool.cn/community/01b71361dd8ce311013f01cdc36e2a.jpg?x-oss-process=image/auto-orient,1/resize,m_lfit,w_1280,limit_1/sharpen,100/format,webp/quality,q_100" onerror='onerror=null,src="https://npm.elemecdn.com/akiblog@1.0.1/img/loading.gif"' alt="cover of next post"><div class="pagination-info"><div class="label">下一篇</div><div class="next_info">7月15日 星期四 晴</div></div></div></div></nav><div class="business-center"><div class="business-card"><div class="business-flip"><div class="business-front"><div class="business-strip-bottom"></div><div class="business-strip-top"></div><img class="business-logo" width="80" height="80" src="" data-lazy-src="https://npm.elemecdn.com/akiblog@1.0.1/img/cardcode.png" alt="cardcode"><div class="business-Invitation">Invitation</div><div class="business-chip"><div class="business-chip-line"></div><div class="business-chip-line"></div><div class="business-chip-line"></div><div class="business-chip-line"></div><div class="business-chip-main"></div></div><svg class="business-wave" viewBox="0 3.71 26.959 38.787" width="26.959" height="38.787" fill="white"><path d="M19.709 3.719c.266.043.5.187.656.406 4.125 5.207 6.594 11.781 6.594 18.938 0 7.156-2.469 13.73-6.594 18.937-.195.336-.57.531-.957.492a.9946.9946 0 0 1-.851-.66c-.129-.367-.035-.777.246-1.051 3.855-4.867 6.156-11.023 6.156-17.718 0-6.696-2.301-12.852-6.156-17.719-.262-.317-.301-.762-.102-1.121.204-.36.602-.559 1.008-.504z"></path><path d="M13.74 7.563c.231.039.442.164.594.343 3.508 4.059 5.625 9.371 5.625 15.157 0 5.785-2.113 11.097-5.625 15.156-.363.422-1 .472-1.422.109-.422-.363-.472-1-.109-1.422 3.211-3.711 5.156-8.551 5.156-13.843 0-5.293-1.949-10.133-5.156-13.844-.27-.309-.324-.75-.141-1.114.188-.367.578-.582.985-.542h.093z"></path><path d="M7.584 11.438c.227.031.438.144.594.312 2.953 2.863 4.781 6.875 4.781 11.313 0 4.433-1.828 8.449-4.781 11.312-.398.387-1.035.383-1.422-.016-.387-.398-.383-1.035.016-1.421 2.582-2.504 4.187-5.993 4.187-9.875 0-3.883-1.605-7.372-4.187-9.875-.321-.282-.426-.739-.266-1.133.164-.395.559-.641.984-.617h.094zM1.178 15.531c.121.02.238.063.344.125 2.633 1.414 4.437 4.215 4.437 7.407 0 3.195-1.797 5.996-4.437 7.406-.492.258-1.102.07-1.36-.422-.257-.492-.07-1.102.422-1.359 2.012-1.075 3.375-3.176 3.375-5.625 0-2.446-1.371-4.551-3.375-5.625-.441-.204-.676-.692-.551-1.165.122-.468.567-.785 1.051-.742h.094z"></path></svg><div class="business-card-number"><div class="business-section">Akilar</div><div class="business-section">589330978</div></div><div class="business-end"><span class="business-end-text">created:</span><span class="business-end-date">14/10/2022</span></div><div class="business-card-holder">Welcome to Candyhome</div><div class="business-master"><div class="business-circle business-master-red"></div><div class="business-circle business-master-yellow"></div></div></div><div class="business-back"><div class="business-strip-black"></div><div class="business-ccv"><label>sitelink</label><div><a target="_blank" rel="noopener external nofollow noreferrer" href="https://jq.qq.com/?_wv=1027&k=5o4Iga8D">加入群聊【🧊Akilarの糖果屋🍭】</a></div></div><div class="business-terms"><p>Use this card to join the candyhome and participate in a pleasant discussion together .</p><p>Welcome to Akilar's candyhome,wish you a nice day .</p></div></div></div></div></div><hr><div id="post-comment"><div class="comment-head"><div class="comment-headline"><i class="fas fa-comments fa-fw"></i> <span>评论</span></div></div><div class="comment-wrap"><div><div id="twikoo-wrap"></div></div></div></div></div><div class="aside-content" id="aside-content"><div class="card-widget card-author"><div class="item-headline"><i class="fa-solid fa-circle-user"></i><span>作者信息</span></div><div class="author-main-content"><div class="author-check-content"><label class="author-info" for="author-info"><input id="author-info" type="checkbox" name="author-info"><div class="author-avatar"><img src="" data-lazy-src="https://npm.elemecdn.com/akiblog@1.0.1/img/author.webp" onerror='this.onerror=null,this.src="https://npm.elemecdn.com/akiblog@1.0.1/img/404.gif"' alt="avatar"></div><div class="author-name">Akilar</div></label></div><div class="author-switch-content"><input class="switch-content" type="radio" name="switch-content" value="description"><label class="author-description-box"><div class="author-description">流水幽吟绕耳边，<br>煦风馨语抚心弦，<br>挥臂欲揽冰钩月，<br>银星斟酌醉人涎。</div></label><input class="switch-content" type="radio" name="switch-content" value="social" checked><label class="author-social-box"><a class="card-author-button" target="_blank" rel="noopener external nofollow noreferrer" href="https://jq.qq.com/?_wv=1027&amp;k=tNuEdliQ"><i class="fa fa-paper-plane faa-tada"></i><span>加入糖果屋群聊</span></a><div class="social-icons"><a class="social-icon faa-parent animated-hover" href="https://github.com/Akilarlxh" rel="external nofollow noreferrer" target="_blank" title="Github"><svg class="icon faa-tada" aria-hidden="true"><use xlink:href="#icon-identity-01"></use></svg></a><a class="social-icon faa-parent animated-hover" href="mailto:Akilarlxh@gmail.com" rel="external nofollow noreferrer" target="_blank" title="Email"><svg class="icon faa-tada" aria-hidden="true"><use xlink:href="#icon-Openmail-01"></use></svg></a><a class="social-icon faa-parent animated-hover" href="https://space.bilibili.com/22976782" rel="external nofollow noreferrer" target="_blank" title="Bilibili"><svg class="icon faa-tada" aria-hidden="true"><use xlink:href="#icon-film-01"></use></svg></a><a class="social-icon faa-parent animated-hover" href="https://music.163.com/#/user/home?id=292643778" rel="external nofollow noreferrer" target="_blank" title="Cloudmusic"><svg class="icon faa-tada" aria-hidden="true"><use xlink:href="#icon-songlist-01"></use></svg></a><a class="social-icon faa-parent animated-hover" href="/atom.xml" target="_blank" title="RSS"><svg class="icon faa-tada" aria-hidden="true"><use xlink:href="#icon-pushpin-01"></use></svg></a></div></label><input class="switch-content" type="radio" name="switch-content" value="site-data"><label class="author-data-box"><div class="site-data"><a class="data-item" href="/archives/"><div class="data-name">文章</div><div class="data-length">480</div></a><a class="data-item" href="/tags/"><div class="data-name">标签</div><div class="data-length">63</div></a><a class="data-item" href="/categories/"><div class="data-name">分类</div><div class="data-length">6</div></a></div></label></div></div></div><div class="sticky_layout"><div class="card-widget" id="card-toc"><div class="item-headline"><i class="fas fa-stream"></i><span>目录</span><span class="toc-percentage"></span></div><div class="toc-content"><ol class="toc"><li class="toc-item toc-level-2"><a class="toc-link" href="#NPM%E6%8F%92%E4%BB%B6%E7%9A%84%E5%8F%91%E5%B8%83"><span class="toc-number">1.</span> <span class="toc-text">NPM插件的发布</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#%E6%95%99%E7%A8%8B%E6%8B%86%E8%A7%A3"><span class="toc-number">2.</span> <span class="toc-text">教程拆解</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#%E5%85%B7%E4%BD%93%E7%A4%BA%E4%BE%8B"><span class="toc-number">3.</span> <span class="toc-text">具体示例</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#%E6%9B%B4%E5%A4%9A%E5%B7%B2%E5%BC%80%E5%8F%91%E6%8F%92%E4%BB%B6"><span class="toc-number">4.</span> <span class="toc-text">更多已开发插件</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#TO-DO"><span class="toc-number">5.</span> <span class="toc-text">TO DO</span></a></li></ol></div></div><div class="card-widget card-recommend-post"><div class="item-headline"><i class="fas fa-dharmachakra"></i><span>相关推荐</span></div><div class="aside-list"><div class="aside-list-item"><a class="thumbnail" href="/posts/e82444a6/" title="jsdelivr在大陆的icp备案挂了以后，虽然NPM依然还有很多镜像节点可以使用，但是github却一下子成了孤儿。此文通过github action，将博客部署仓库username.github.io推送到npm上，从而实现对npm的CDN镜像节点的利用。"><img src="" data-lazy-src="https://img.zcool.cn/community/0192b161e57b6011013f01cda2eb5e.jpg?x-oss-process=image/auto-orient,1/resize,m_lfit,w_1280,limit_1/sharpen,100/format,webp/quality,q_100" alt="jsdelivr在大陆的icp备案挂了以后，虽然NPM依然还有很多镜像节点可以使用，但是github却一下子成了孤儿。此文通过github action，将博客部署仓库username.github.io推送到npm上，从而实现对npm的CDN镜像节点的利用。"></a><div class="content"><a class="title" href="/posts/e82444a6/" title="使用github-action推送博客部署仓库至NPM">使用github-action推送博客部署仓库至NPM</a><time datetime="2022-01-17" title="发表于 2022-01-17">2022-01-17</time></div></div><div class="aside-list-item"><a class="thumbnail" href="/posts/e2bf861f/" title="俗话说授人以鱼不如授人以渔————本篇详细介绍外挂标签DIY"><img src="" data-lazy-src="https://img.zcool.cn/community/01f28461e1626511013f01cd1d05d8.jpg?x-oss-process=image/auto-orient,1/resize,m_lfit,w_1280,limit_1/sharpen,100/format,webp/quality,q_100" alt="俗话说授人以鱼不如授人以渔————本篇详细介绍外挂标签DIY"></a><div class="content"><a class="title" href="/posts/e2bf861f/" title="DIY外挂标签的简单写法与应用">DIY外挂标签的简单写法与应用</a><time datetime="2020-12-28" title="发表于 2020-12-28">2020-12-28</time></div></div><div class="aside-list-item"><a class="thumbnail" href="/posts/1da4f99e/" title="编写工具介绍"><img src="" data-lazy-src="https://img.zcool.cn/community/01b71361dd8ce311013f01cdc36e2a.jpg?x-oss-process=image/auto-orient,1/resize,m_lfit,w_1280,limit_1/sharpen,100/format,webp/quality,q_100" alt="编写工具介绍"></a><div class="content"><a class="title" href="/posts/1da4f99e/" title="Hexo-editor——Hexo专用的编辑器">Hexo-editor——Hexo专用的编辑器</a><time datetime="2019-04-23" title="发表于 2019-04-23">2019-04-23</time></div></div><div class="aside-list-item"><a class="thumbnail" href="/posts/61b3e163/" title="访问github或部署在gitpage上的网站过慢的解决方案"><img src="" data-lazy-src="https://img.zcool.cn/community/01729c61dd8ce711013f01cd0f12a3.jpg?x-oss-process=image/auto-orient,1/resize,m_lfit,w_1280,limit_1/sharpen,100/format,webp/quality,q_100" alt="访问github或部署在gitpage上的网站过慢的解决方案"></a><div class="content"><a class="title" href="/posts/61b3e163/" title="github faster">github faster</a><time datetime="2020-07-29" title="发表于 2020-07-29">2020-07-29</time></div></div><div class="aside-list-item"><a class="thumbnail" href="/posts/3e956346/" title="picgo+jsDelivr+github的进阶教程，在这一基础上增加npm图床的活用方式，使用github action实现自动发布。"><img src="" data-lazy-src="https://npm.elemecdn.com/akilar-candyassets/image/20201115152231.png" alt="picgo+jsDelivr+github的进阶教程，在这一基础上增加npm图床的活用方式，使用github action实现自动发布。"></a><div class="content"><a class="title" href="/posts/3e956346/" title="npm图床的使用技巧">npm图床的使用技巧</a><time datetime="2021-05-11" title="发表于 2021-05-11">2021-05-11</time></div></div><div class="aside-list-item"><a class="thumbnail" href="/posts/bbf68ad4/" title="魔改后的主题直接升级显然是很困难的，但是换个思路，如果把主题升级也看作是一次魔改呢？"><img src="" data-lazy-src="https://img.zcool.cn/community/01593e61dd8ce411013e8cd0aa8bab.jpg?x-oss-process=image/auto-orient,1/resize,m_lfit,w_1280,limit_1/sharpen,100/format,webp/quality,q_100" alt="魔改后的主题直接升级显然是很困难的，但是换个思路，如果把主题升级也看作是一次魔改呢？"></a><div class="content"><a class="title" href="/posts/bbf68ad4/" title="平滑升级魔改后的Hexo主题">平滑升级魔改后的Hexo主题</a><time datetime="2020-10-14" title="发表于 2020-10-14">2020-10-14</time></div></div></div></div></div></div></main><footer id="footer"><div id="ark-footer-wraper"><div class="ark-footer-container"><div class="ark-footer-left-corner"><div id="ark-footer-bdage-container"><div class="ark-footer-bdage swiper-wrapper"><a class="ark-bdage-item swiper-slide" href="https://hexo.io/" rel="external nofollow noreferrer" title="博客框架为Hexo_v6.2.0" target="_blank"><svg class="icon ark-decoration" aria-hidden="true"><use xlink:href="#icon-hexo"></use></svg><span>Frame-Hexo</span></a><a class="ark-bdage-item swiper-slide" href="https://butterfly.js.org/" rel="external nofollow noreferrer" title="主题版本Butterfly_v4.4.0" target="_blank"><svg class="icon ark-decoration" aria-hidden="true"><use xlink:href="#icon-Butterfly"></use></svg><span>Theme-Butterfly</span></a><a class="ark-bdage-item swiper-slide" href="https://www.jsdelivr.com/" rel="external nofollow noreferrer" title="本站使用JsDelivr为静态资源提供CDN加速" target="_blank"><svg class="icon ark-decoration" aria-hidden="true"><use xlink:href="#icon-jsdelivr"></use></svg><span>CDN-jsDelivr</span></a><a class="ark-bdage-item swiper-slide" href="https://console.dogecloud.com/" rel="external nofollow noreferrer" title="本网站由多吉云提供CDN加速服务" target="_blank"><svg class="icon ark-decoration" aria-hidden="true"><use xlink:href="#icon-DOGE"></use></svg><span>CDN-dogecloud</span></a><a class="ark-bdage-item swiper-slide" href="https://beian.miit.gov.cn" title="本站已在工信部备案，备案号浙ICP备-2021026687号" target="_blank"><svg class="icon ark-decoration" aria-hidden="true"><use xlink:href="#icon-a-255_icp-license"></use></svg><span>ICP-2021026687-1</span></a><a class="ark-bdage-item swiper-slide" href="https://icp.gov.moe/?keyword=20212887" title="本站已加入萌ICP豪华套餐，萌ICP备20212887号" target="_blank"><svg class="icon ark-decoration" aria-hidden="true"><use xlink:href="#icon-space_demo_equipment"></use></svg><span>moeICP-20212887</span></a><a class="ark-bdage-item swiper-slide" href="https://www.netlify.com/" rel="external nofollow noreferrer" title="本站默认线路托管于Netlify" target="_blank"><svg class="icon ark-decoration" aria-hidden="true"><use xlink:href="#icon-netlify"></use></svg><span>Hosted-Netlify</span></a><a class="ark-bdage-item swiper-slide" href="https://github.com/" rel="external nofollow noreferrer" title="本站项目由Github托管" target="_blank"><svg class="icon ark-decoration" aria-hidden="true"><use xlink:href="#icon-GitHub"></use></svg><span>Source-Github</span></a><a class="ark-bdage-item swiper-slide" href="http://creativecommons.org/licenses/by-nc-sa/4.0/" rel="external nofollow noreferrer" title="本站采用知识共享署名-非商业性使用-相同方式共享4.0国际许可协议进行许可" target="_blank"><svg class="icon ark-decoration" aria-hidden="true"><use xlink:href="#icon-copyright"></use></svg><span>Copyright-BY-NC-SA-4</span></a></div></div><div class="ark-footer-copyright">&copy;2016 - 2023 By Akilar</div><a class="ark-footer-record" target="_blank" rel="noopener" href="https://beian.miit.gov.cn" title="浙ICP备-2021026687号">浙ICP备-2021026687号</a></div><div class="ark-footer-right-corner"><div id="workboard"></div><script async src="/js/custom/runtime.js"></script></div></div></div></footer></div><div id="rightside"><div id="rightside-config-hide"><button id="readmode" type="button" title="阅读模式"><i class="fas fa-book-open faa-pulse animated-hover"></i><span>阅读模式</span></button><button id="translateLink" type="button" title="简繁转换"><i>繁</i><span>简繁转换</span></button><a class="icon-V hidden" onclick="switchNightMode()" title="昼夜切换"><svg class="faa-pulse animated-hover" width="25" height="25" viewBox="0 0 1024 1024"><use id="modeicon" xlink:href="#icon-moon"></use></svg><span>昼夜切换</span></a><button id="hide-aside-btn" type="button" title="侧栏显隐"><i class="fas fa-arrows-alt-h faa-pulse animated-hover"></i><span>侧栏显隐</span></button><button id="SAO_Utils_Switch" type="button" title="右键开关" onclick="panelAudio(),SAOSwitch()"><i class="fas fa-mouse faa-pulse animated-hover"></i><span>右键开关</span></button><button id="SAO_Utils_Refresh" type="button" title="点击刷新" onclick="panelAudio(),fetchCommits()"><i class="fa-solid fa-arrows-rotate faa-pulse animated-hover"></i><span>点击刷新</span></button></div><div id="rightside-config-show"><button id="rightside_config" type="button" title="设置"><i class="fas fa-cog fa-spin faa-pulse animated-hover"></i><span>设置</span></button><button id="ranklist_show" type="button" title="打赏榜单" onclick="panelAudio(),RanklistBtn()"><i class="fas fa-fire-alt faa-pulse animated-hover"></i><span>打赏榜单</span></button><button class="close" id="mobile-toc-button" type="button" title="目录"><i class="fas fa-list-ul faa-pulse animated-hover"></i><span>目录</span></button><button id="chat_btn" type="button" title="与我联系"><i class="fas fa-sms faa-pulse animated-hover"></i><span>与我联系</span></button><button id="to_comment" type="button" title="直达评论" onclick="FixedCommentBtn()"><i class="fas fa-comments faa-pulse animated-hover"></i><span>直达评论</span></button><button id="go-up" type="button" title="回到顶部"><i class="fas fa-arrow-up faa-pulse animated-hover"></i><span>回到顶部</span></button></div></div><div id="algolia-search"><div class="search-dialog"><nav class="search-nav"><span class="search-dialog-title">搜索</span><button class="search-close-button"><i class="fas fa-times"></i></button></nav><div class="search-wrap"><div id="algolia-search-input"></div><hr><div id="algolia-search-results"><div id="algolia-hits"></div><div id="algolia-pagination"></div><div id="algolia-info"><div class="algolia-stats"></div><div class="algolia-poweredBy"></div></div></div></div></div><div id="search-mask"></div></div><div><script async src="https://npm.elemecdn.com/akiblog@1.0.1/js/custom/async.js"></script><script src="https://npm.elemecdn.com/akiblog@1.0.1/js/utils.js"></script><script src="https://npm.elemecdn.com/akiblog@1.0.1/js/main.js"></script><script defer src="https://npm.elemecdn.com/swiper@8.4.2/swiper-bundle.min.js"></script><script defer data-pjax src="/js/custom/swiper_init.js"></script><script src="https://npm.elemecdn.com/akiblog@1.0.1/js/tw_cn.js"></script><script src="https://npm.elemecdn.com/medium-zoom@1.0.6/dist/medium-zoom.min.js"></script><script src="https://npm.elemecdn.com/instant.page@5.1.1/instantpage.js" type="module"></script><script src="https://npm.elemecdn.com/vanilla-lazyload@17.3.1/dist/lazyload.iife.min.js"></script><script src="https://npm.elemecdn.com/node-snackbar@0.1.16/dist/snackbar.min.js"></script><script src="https://npm.elemecdn.com/algoliasearch@4.14.2/dist/algoliasearch-lite.umd.js"></script><script src="https://npm.elemecdn.com/instantsearch.js@4.44.0/dist/instantsearch.production.min.js"></script><script src="https://npm.elemecdn.com/akiblog@1.0.1/js/search/algolia.js"></script><div class="pjax-reload"><script async>var preloader={endLoading:()=>{if(document.body.style.overflow="auto",document.getElementById("loading-box").style.transition="opacity 3s",document.getElementById("loading-box").style.opacity="0",setTimeout((function(){document.getElementById("loading-box").classList.add("loaded")}),3e3),sessionStorage.getItem("isReload"))return!0;sessionStorage.setItem("isReload",!0),SAONotify("Welcome","欢迎光临糖果屋<br>愿你享受愉快的一天")},initLoading:()=>{document.body.style.overflow="",document.getElementById("loading-box").style.transition="",document.getElementById("loading-box").style.opacity="1",document.getElementById("loading-box").classList.remove("loaded")}};window.addEventListener("load",()=>{preloader.endLoading()}),document.getElementById("loading-box").addEventListener("click",()=>{preloader.endLoading()}),setTimeout((function(){preloader.endLoading()}),3e3)</script></div><div class="js-pjax"><script>(()=>{const t=()=>{twikoo.init(Object.assign({el:"#twikoo-wrap",envId:"https://twikoo-service.akilar.top",region:"",onCommentLoaded:function(){btf.loadLightbox(document.querySelectorAll("#twikoo .tk-content img:not(.tk-owo-emotion)"))}},null))},o=()=>{"object"!=typeof twikoo?getScript("https://npm.elemecdn.com/twikoo@1.6.5/dist/twikoo.all.min.js").then(t):setTimeout(t,0)};btf.loadComment(document.getElementById("twikoo-wrap"),o)})()</script></div><script>window.addEventListener("load",()=>{const e=e=>{let t="";if(e.length)for(let n=0;n<e.length;n++){t+="<div class='aside-list-item'>";{const a="data-lazy-src";t+=`<a href='${e[n].url}' class='thumbnail'><img ${a}='${e[n].avatar}' alt='${e[n].nick}'></a>`}t+=`<div class='content'>\n        <a class='comment' href='${e[n].url}' title='${e[n].content}'>${e[n].content}</a>\n        <div class='name'><span>${e[n].nick} / </span><time datetime="${e[n].date}">${btf.diffDate(e[n].date,!0)}</time></div>\n        </div></div>`}else t+="没有评论";let n=document.querySelector("#card-newest-comments .aside-list");n.innerHTML=t,window.lazyLoadInstance&&window.lazyLoadInstance.update(),window.pjax&&window.pjax.refresh(n)},t=()=>{if(document.querySelector("#card-newest-comments .aside-list")){const t=saveToLocal.get("twikoo-newest-comments");t?e(JSON.parse(t)):(()=>{const t=()=>{twikoo.getRecentComments({envId:"https://twikoo-service.akilar.top",region:"",pageSize:5,includeReply:!0}).then((function(t){const n=t.map(e=>{return{content:(t=e.comment,""===t||(t=(t=(t=(t=t.replace(/<img.*?src="(.*?)"?[^\>]+>/gi,"[图片]")).replace(/<a[^>]+?href=["']?([^"']+)["']?[^>]*>([^<]+)<\/a>/gi,"[链接]")).replace(/<pre><code>.*?<\/pre>/gi,"[代码]")).replace(/<[^>]+>/g,"")).length>150&&(t=t.substring(0,150)+"..."),t),avatar:e.avatar,nick:e.nick,url:e.url+"#"+e.id,date:new Date(e.created).toISOString()};var t});saveToLocal.set("twikoo-newest-comments",JSON.stringify(n),10/1440),e(n)})).catch((function(e){document.querySelector("#card-newest-comments .aside-list").innerHTML="无法获取评论，请确认相关配置是否正确"}))};"object"==typeof twikoo?t():getScript("https://npm.elemecdn.com/twikoo@1.6.5/dist/twikoo.all.min.js").then(t)})()}};t(),document.addEventListener("pjax:complete",t)})</script><script src="https://npm.elemecdn.com/akiblog@1.0.1/js/custom/sun_moon.js" async></script><script async data-pjax src="https://npm.elemecdn.com/akiblog@1.0.1/js/custom/SAO-NAV.js"></script><script>WIDGET={CONFIG:{modules:"012",background:"5",tmpColor:"FFFFFF",tmpSize:"16",cityColor:"FFFFFF",citySize:"16",aqiColor:"FFFFFF",aqiSize:"16",weatherIconSize:"24",alertIconSize:"18",padding:"10px 10px 10px 10px",shadow:"0",language:"auto",fixed:"false",vertical:"top",horizontal:"left",key:"3da94e567f5e4e88baf90f066f0893c2"}}</script><script defer data-pjax src="https://widget.heweather.net/simple/static/js/he-simple.js?v=1.4.0"></script><script async src="https://npm.elemecdn.com/akiblog@1.0.1/js/custom/random.js"></script><script defer src="https://at.alicdn.com/t/c/font_3344355_e443xsjcmum.js"></script><script src="//code.tidio.co/wgamdwbirypo8casl6rjgtfbs47ny3s7.js" async></script><script>function onTidioChatApiReady(){window.tidioChatApi.hide(),window.tidioChatApi.on("close",(function(){window.tidioChatApi.hide()}))}window.tidioChatApi?window.tidioChatApi.on("ready",onTidioChatApiReady):document.addEventListener("tidioChat-ready",onTidioChatApiReady);var chatBtnFn=()=>{document.getElementById("chat_btn").addEventListener("click",(function(){window.tidioChatApi.show(),window.tidioChatApi.open()}))};chatBtnFn()</script><script src="https://npm.elemecdn.com/pjax@0.2.8/pjax.min.js"></script><script>let pjaxSelectors=["head > title","#config-diff","#body-wrap","#rightside-config-hide","#rightside-config-show",".js-pjax","#web_bg","#fixedcard-dashboard"];var pjax=new Pjax({elements:'a:not([target="_blank"])',selectors:pjaxSelectors,cacheBust:!1,analytics:!1,scrollRestoration:!1});document.addEventListener("pjax:send",(function(){if(window.tocScrollFn&&window.removeEventListener("scroll",window.tocScrollFn),window.scrollCollect&&window.removeEventListener("scroll",scrollCollect),"object"==typeof preloader&&preloader.initLoading(),document.getElementById("rightside").style.cssText="opacity: ''; transform: ''",window.aplayers)for(let e=0;e<window.aplayers.length;e++)window.aplayers[e].options.fixed||window.aplayers[e].destroy();"object"==typeof typed&&typed.destroy();const e=document.body.classList;e.contains("read-mode")&&e.remove("read-mode"),"object"==typeof disqusjs&&disqusjs.destroy()})),document.addEventListener("pjax:complete",(function(){window.refreshFn(),document.querySelectorAll("script[data-pjax], .pjax-reload script").forEach(e=>{const t=document.createElement("script"),o=e.text||e.textContent||e.innerHTML||"";Array.from(e.attributes).forEach(e=>t.setAttribute(e.name,e.value)),t.appendChild(document.createTextNode(o)),e.parentNode.replaceChild(t,e)}),GLOBAL_CONFIG.islazyload&&window.lazyLoadInstance.update(),"function"==typeof chatBtnFn&&chatBtnFn(),"function"==typeof panguInit&&panguInit(),"function"==typeof gtag&&gtag("config","",{page_path:window.location.pathname}),"object"==typeof _hmt&&_hmt.push(["_trackPageview",window.location.pathname]),"function"==typeof loadMeting&&document.getElementsByClassName("aplayer").length&&loadMeting(),"object"==typeof Prism&&Prism.highlightAll(),"object"==typeof preloader&&preloader.endLoading()})),document.addEventListener("pjax:error",e=>{404===e.request.status&&pjax.loadUrl("/404.html")})</script><script>"serviceWorker"in navigator&&(navigator.serviceWorker.controller&&navigator.serviceWorker.addEventListener("controllerchange",(function(){fetch("/json/commits.json").then(e=>e.json().then(e=>{for(var r=e,o=0;o<r.length;o++){r[o];var t=o+1+"."+r[o].commit.message;if(o<1)var n=t;else n=n+"<br>"+t}SAONotify("Latest Update",n,"location.reload(true);")})).catch(console.error)})),window.addEventListener("load",(function(){navigator.serviceWorker.register("/sw.js")})))</script><div id="SAO-back"><div id="SAO-menu"><div id="SAO-menu-content"><div class="utils-list"><div class="utils-list-item"><div class="user-panel" style="top:undefined"><div class="user-panel-name">Friends</div><div class="user-panel-img"><img src="" data-lazy-src="/img/info.png"></div><div class="user-panel-properties">Welcome to Akilar の Candyhome !</div></div><i class="fas fa-address-book" onclick="panelAudio(),UtilsClick()"></i><div class="menu-list" style="top:-83px"><div class="menu-list-item"><i class="fa fa-link" onclick='clickAudio(),setTimeout((function(){SAOclose(),linkStart("/link/")}),500)'>Link</i></div><div class="menu-list-item"><i class="fas fa-fire-alt" onclick="clickAudio(),setTimeout((function(){SAOclose(),RanklistBtn()}),500)">Pantner</i></div></div></div><div class="utils-list-item"><div class="user-panel" style="top:undefined"><div class="user-panel-name">Help</div><div class="user-panel-img"><img src="" data-lazy-src="/img/info.png"></div><div class="user-panel-properties"><h4>Anything can I help you ?</h4><p>Tidio：开启在线聊天窗<br>Comment：直达评论区或留言板<br>Candyhome：加入糖果屋QQ群</p></div></div><i class="fa fa-question-circle" onclick="panelAudio(),UtilsClick()"></i><div class="menu-list" style="top:-103px"><div class="menu-list-item"><i class="fa fa-comment-dots" onclick="clickAudio(),setTimeout((function(){SAOclose(),openTidio()}),500)">Tidio</i></div><div class="menu-list-item"><i class="fa fa-comments" onclick="clickAudio(),setTimeout((function(){SAOclose(),FixedCommentBtn()}),500)">Comments</i></div><div class="menu-list-item"><i class="fa fa-user-friends" onclick='clickAudio(),setTimeout((function(){SAOclose(),linkStart("https://jq.qq.com/?_wv=1027&amp;k=a08BZRzs")}),500)'>Candyhome</i></div></div></div><div class="utils-list-item"><div class="user-panel" style="top:undefined"><div class="user-panel-name">Menu</div><div class="user-panel-img"><img src="" data-lazy-src="/img/info.png"></div><div class="user-panel-properties">The menu of my blog</div></div><i class="fa fa-tasks" onclick="panelAudio(),UtilsClick()"></i><div class="menu-list" style="top:-163px"><div class="menu-list-item"><i class="fa fa-home" onclick='clickAudio(),setTimeout((function(){SAOclose(),linkStart("https://blog.akilar.top/")}),500)'>Home</i></div><div class="menu-list-item"><i class="fa fa-folder-open" onclick="panelAudio(),MenusClick()">Document</i><div class="menu-child" style="top:-100px"><div class="menu-list-child"><i class="fa fa-file-invoice" onclick='clickAudio(),setTimeout((function(){SAOclose(),linkStart("/posts/f99b208/")}),500)'>Beautify</i></div><div class="menu-list-child"><i class="fa fa-file-invoice" onclick='clickAudio(),setTimeout((function(){SAOclose(),linkStart("/posts/7c16c4bb/")}),500)'>Optimize</i></div><div class="menu-list-child"><i class="fa fa-file-invoice" onclick='clickAudio(),setTimeout((function(){SAOclose(),linkStart("/posts/615e2dec/")}),500)'>Tag_Plugins</i></div><div class="menu-list-child"><i class="fa fa-file-invoice" onclick='clickAudio(),setTimeout((function(){SAOclose(),linkStart("/posts/6ef63e2d/")}),500)'>Construct</i></div></div></div><div class="menu-list-item"><i class="fa fa-blog" onclick='clickAudio(),setTimeout((function(){SAOclose(),linkStart("/")}),500)'>Blog</i></div><div class="menu-list-item"><i class="fa fa-archive" onclick='clickAudio(),setTimeout((function(){SAOclose(),linkStart("/archives/")}),500)'>Archives</i></div><div class="menu-list-item"><i class="fa fa-folder-open" onclick='clickAudio(),setTimeout((function(){SAOclose(),linkStart("/categories/")}),500)'>Categoties</i></div><div class="menu-list-item"><i class="fa fa-tags" onclick='clickAudio(),setTimeout((function(){SAOclose(),linkStart("/tags/")}),500)'>Tags</i></div></div></div><div class="utils-list-item"><div class="user-panel" style="top:undefined"><div class="user-panel-name">Options</div><div class="user-panel-img"><img src="" data-lazy-src="/img/info.png"></div><div class="user-panel-properties"><h4>Some userful scripts</h4><p>Random： 随机跳转站内文章<br>Search： 打开搜索窗口</p>Refresh： 刷新缓存</div></div><i class="fa fa-tools" onclick="panelAudio(),UtilsClick()"></i><div class="menu-list" style="top:-103px"><div class="menu-list-item"><i class="fa fa-random" onclick='clickAudio(),setTimeout((function(){SAOclose(),linkStart("/toRandomPost()")}),500)'>Random</i></div><div class="menu-list-item"><i class="fa fa-search" onclick="clickAudio(),setTimeout((function(){SAOclose(),openSearch()}),500)">Search</i></div><div class="menu-list-item"><i class="fa-solid fa-arrows-rotate" onclick='clickAudio(),setTimeout((function(){SAOclose(),SAONotify("Refresh","即将为您刷新页面缓存","location.reload(true);")}),500)'>Refresh</i></div></div></div><div class="utils-list-item"><div class="user-panel"><div class="user-panel-name">Instructions</div><div class="user-panel-img"><img src="" data-lazy-src="/img/siteicon/favicon.png"></div><div class="user-panel-properties"><h4>欢迎使用SAO_Utils_Web 2.0</h4><p>点按选项可以持续显示下级菜单。您可以通过按住<kbd>ctrl</kbd>+<kbd>右键</kbd>来恢复使用原生右键菜单，更多内容可点击右侧Option按钮访问教程或Help按钮加入糖果屋QQ群。</p><center>©Akilarの糖果屋</center></div></div><i class="fa fa-cog" onclick="panelAudio(),UtilsClick()"></i><div class="menu-list" style="top:-103px"><div class="menu-list-item"><i class="fa fa-tools" onclick='clickAudio(),setTimeout((function(){SAOclose(),linkStart("https://akilar.top/posts/fd243d7/")}),500)'>Option</i></div><div class="menu-list-item"><i class="fa fa-question-circle" onclick='clickAudio(),setTimeout((function(){SAOclose(),linkStart("https://jq.qq.com/?_wv=1027&amp;k=a08BZRzs")}),500)'>Help</i></div><div class="menu-list-item"><i class="fa fa-sign-out-alt" onclick="alertAudio(),openLogout()">Logout</i></div></div></div><div class="utils-list-item"><i class="fa fa-power-off" onclick="alertAudio(),SAOKeepOff()" title="永久关闭SAO右键菜单"></i></div></div></div></div></div><div id="SAO-logout"><div class="logout-title">Alert</div><div class="logout-alert">是否确认退出?</div><div class="logout-button"><span class="logout-confirm"><button class="far fa-circle" type="button" name="confirm" onclick="clickAudio(),confirmLogout()"></button></span><span class="logout-cancel"><button class="fa fa-times" type="button" name="cancel" onclick="panelAudio(),cancelLogout()"></button></span></div></div><audio id="SAOlauncher" src="https://npm.elemecdn.com/akilar-candyassets/audio/Launcher.mp3"></audio><audio id="SAOClick" src="https://npm.elemecdn.com/akilar-candyassets/audio/Click.mp3"></audio><audio id="SAOPanel" src="https://npm.elemecdn.com/akilar-candyassets/audio/Panel.mp3"></audio><audio id="SAOAlert" src="https://npm.elemecdn.com/akilar-candyassets/audio/Alert.mp3"></audio><script async src="https://npm.elemecdn.com/akiblog@1.0.1/js/custom/SAO_Menu.js"></script><div id="SAO-ranklist"><div class="ranklist-title">Rank list</div><div class="ranklist-main"><div class="master-item"><div class="master-rank"><i class="fa fa-plus" onclick="panelAudio(),RanklistBtn()"></i></div><div class="master-user"><a alt="" href="/">Akilar<div class="rank-reward"><div class="reward-img"><img alt="" src="" data-lazy-src="https://npm.elemecdn.com/akiblog@1.0.1/img/wechat.png"><a class="reward-text" alt="" href="/null">wechat</a></div><div class="reward-img"><img alt="" src="" data-lazy-src="https://npm.elemecdn.com/akiblog@1.0.1/img/alipay.png"><a class="reward-text" alt="" href="/null">alipay</a></div></div></a></div><div class="master-data"><div class="master-HP"><div class="HP-fill" style="width:20%"><div class="HP-fill-in"><span>20%</span></div></div></div></div><div class="master-level"><span>270</span><span>|</span><span>1350</span><span>lv.23</span></div></div><div class="partner-item"><div class="partner-rank"></div><div class="partner-user"><a alt="" href="javascript:void(0);" rel="external nofollow noreferrer" data-title="感谢*蓓打赏的￥180">*蓓</a></div><div class="partner-data"><div class="partner-HP"><div class="HP-fill" style="width:100%"><div class="HP-fill-in"><span>100.00%</span></div></div></div></div><div class="partner-level"><span>9200</span><span>|</span><span>9200</span><span>lv.180</span></div></div><div class="partner-item"><div class="partner-rank"></div><div class="partner-user"><a alt="" href="javascript:void(0);" rel="external nofollow noreferrer" data-title="感谢晨打赏的￥8.88">晨</a></div><div class="partner-data"><div class="partner-HP"><div class="HP-fill" style="width:88.86%"><div class="HP-fill-in"><span>88.86%</span></div></div></div></div><div class="partner-level"><span>622</span><span>|</span><span>700</span><span>lv.10</span></div></div><div class="partner-item"><div class="partner-rank"></div><div class="partner-user"><a alt="" target="_blank" rel="noopener external nofollow noreferrer" href="https://zfe.space/" data-title="感谢**鄂打赏的￥9.9">**鄂</a></div><div class="partner-data"><div class="partner-HP"><div class="HP-fill" style="width:13.76%"><div class="HP-fill-in"><span>13.76%</span></div></div></div></div><div class="partner-level"><span>523</span><span>|</span><span>3800</span><span>lv.72</span></div></div><div class="partner-item"><div class="partner-rank"></div><div class="partner-user"><a alt="" href="javascript:void(0);" rel="external nofollow noreferrer" data-title="感谢*光打赏的￥50">*光</a></div><div class="partner-data"><div class="partner-HP"><div class="HP-fill" style="width:92.59%"><div class="HP-fill-in"><span>92.59%</span></div></div></div></div><div class="partner-level"><span>2685</span><span>|</span><span>2900</span><span>lv.54</span></div></div><div class="partner-item"><div class="partner-rank"></div><div class="partner-user"><a alt="" href="javascript:void(0);" rel="external nofollow noreferrer" data-title="感谢*洁打赏的￥30">*洁</a></div><div class="partner-data"><div class="partner-HP"><div class="HP-fill" style="width:93.78%"><div class="HP-fill-in"><span>93.78%</span></div></div></div></div><div class="partner-level"><span>1688</span><span>|</span><span>1800</span><span>lv.32</span></div></div><div class="partner-item"><div class="partner-rank"></div><div class="partner-user"><a alt="" href="javascript:void(0);" rel="external nofollow noreferrer" data-title="感谢**焘打赏的￥20">**焘</a></div><div class="partner-data"><div class="partner-HP"><div class="HP-fill" style="width:90.92%"><div class="HP-fill-in"><span>90.92%</span></div></div></div></div><div class="partner-level"><span>1182</span><span>|</span><span>1300</span><span>lv.22</span></div></div><div class="partner-item"><div class="partner-rank"></div><div class="partner-user"><a alt="" target="_blank" rel="noopener external nofollow noreferrer" href="https://szsyzx.github.io/" data-title="感谢懒蟲打赏的￥20">懒蟲</a></div><div class="partner-data"><div class="partner-HP"><div class="HP-fill" style="width:74.06%"><div class="HP-fill-in"><span>74.06%</span></div></div></div></div><div class="partner-level"><span>1148</span><span>|</span><span>1550</span><span>lv.27</span></div></div><div class="partner-item"><div class="partner-rank"></div><div class="partner-user"><a alt="" href="javascript:void(0);" rel="external nofollow noreferrer" data-title="感谢*i打赏的￥10">*i</a></div><div class="partner-data"><div class="partner-HP"><div class="HP-fill" style="width:83.38%"><div class="HP-fill-in"><span>83.38%</span></div></div></div></div><div class="partner-level"><span>667</span><span>|</span><span>800</span><span>lv.12</span></div></div><div class="partner-item"><div class="partner-rank"></div><div class="partner-user"><a alt="" target="_blank" rel="noopener external nofollow noreferrer" href="https://www.acozycotage.net/" data-title="感谢acozycotage打赏的￥10">acozycotage</a></div><div class="partner-data"><div class="partner-HP"><div class="HP-fill" style="width:NaN%"><div class="HP-fill-in"><span>NaN%</span></div></div></div></div><div class="partner-level"><span>NaN</span><span>|</span><span>NaN</span><span>lv.undefined</span></div></div><div class="partner-item"><div class="partner-rank"></div><div class="partner-user"><a alt="" href="javascript:void(0);" rel="external nofollow noreferrer" data-title="感谢*因打赏的￥10">*因</a></div><div class="partner-data"><div class="partner-HP"><div class="HP-fill" style="width:62.5%"><div class="HP-fill-in"><span>62.50%</span></div></div></div></div><div class="partner-level"><span>625</span><span>|</span><span>1000</span><span>lv.16</span></div></div><div class="partner-item"><div class="partner-rank"></div><div class="partner-user"><a alt="" href="javascript:void(0);" rel="external nofollow noreferrer" data-title="感谢H*g打赏的￥10">H*g</a></div><div class="partner-data"><div class="partner-HP"><div class="HP-fill" style="width:83.38%"><div class="HP-fill-in"><span>83.38%</span></div></div></div></div><div class="partner-level"><span>667</span><span>|</span><span>800</span><span>lv.12</span></div></div><div class="partner-item"><div class="partner-rank"></div><div class="partner-user"><a alt="" href="javascript:void(0);" rel="external nofollow noreferrer" data-title="感谢**宁打赏的￥10">**宁</a></div><div class="partner-data"><div class="partner-HP"><div class="HP-fill" style="width:45.46%"><div class="HP-fill-in"><span>45.46%</span></div></div></div></div><div class="partner-level"><span>591</span><span>|</span><span>1300</span><span>lv.22</span></div></div><div class="partner-item"><div class="partner-rank"></div><div class="partner-user"><a alt="" target="_blank" rel="noopener external nofollow noreferrer" href="https://www.nesxc.com/" data-title="感谢Nesxc打赏的￥14.88">Nesxc</a></div><div class="partner-data"><div class="partner-HP"><div class="HP-fill" style="width:74.42%"><div class="HP-fill-in"><span>74.42%</span></div></div></div></div><div class="partner-level"><span>893</span><span>|</span><span>1200</span><span>lv.20</span></div></div><div class="partner-item"><div class="partner-rank"></div><div class="partner-user"><a alt="" href="javascript:void(0);" rel="external nofollow noreferrer" data-title="感谢J*y打赏的￥2.56">J*y</a></div><div class="partner-data"><div class="partner-HP"><div class="HP-fill" style="width:51.11%"><div class="HP-fill-in"><span>51.11%</span></div></div></div></div><div class="partner-level"><span>230</span><span>|</span><span>450</span><span>lv.5</span></div></div><div class="partner-item"><div class="partner-rank"></div><div class="partner-user"><a alt="" target="_blank" rel="noopener external nofollow noreferrer" href="https://www.lbihua.cn" data-title="感谢哔哗打赏的￥10">哔哗</a></div><div class="partner-data"><div class="partner-HP"><div class="HP-fill" style="width:62.5%"><div class="HP-fill-in"><span>62.50%</span></div></div></div></div><div class="partner-level"><span>625</span><span>|</span><span>1000</span><span>lv.16</span></div></div><div class="partner-item"><div class="partner-rank"></div><div class="partner-user"><a alt="" target="_blank" rel="noopener external nofollow noreferrer" href="https://iori-yimaga.top" data-title="感谢T*0打赏的￥23.3">T*0</a></div><div class="partner-data"><div class="partner-HP"><div class="HP-fill" style="width:93.17%"><div class="HP-fill-in"><span>93.17%</span></div></div></div></div><div class="partner-level"><span>1351</span><span>|</span><span>1450</span><span>lv.25</span></div></div><div class="partner-item"><div class="partner-rank"></div><div class="partner-user"><a alt="" href="javascript:void(0);" rel="external nofollow noreferrer" data-title="感谢**飞打赏的￥20">**飞</a></div><div class="partner-data"><div class="partner-HP"><div class="HP-fill" style="width:74.06%"><div class="HP-fill-in"><span>74.06%</span></div></div></div></div><div class="partner-level"><span>1148</span><span>|</span><span>1550</span><span>lv.27</span></div></div><div class="partner-item"><div class="partner-rank"></div><div class="partner-user"><a alt="" href="javascript:void(0);" rel="external nofollow noreferrer" data-title="感谢**豪打赏的￥10">**豪</a></div><div class="partner-data"><div class="partner-HP"><div class="HP-fill" style="width:83.38%"><div class="HP-fill-in"><span>83.38%</span></div></div></div></div><div class="partner-level"><span>667</span><span>|</span><span>800</span><span>lv.12</span></div></div><div class="partner-item"><div class="partner-rank"></div><div class="partner-user"><a alt="" target="_blank" rel="noopener external nofollow noreferrer" href="https://www.keyiqingxin.cn" data-title="感谢清心打赏的￥3.88">清心</a></div><div class="partner-data"><div class="partner-HP"><div class="HP-fill" style="width:19.42%"><div class="HP-fill-in"><span>19.42%</span></div></div></div></div><div class="partner-level"><span>233</span><span>|</span><span>1200</span><span>lv.20</span></div></div><div class="partner-item"><div class="partner-rank"></div><div class="partner-user"><a alt="" href="javascript:void(0);" rel="external nofollow noreferrer" data-title="感谢鹿栖打赏的￥20">鹿栖</a></div><div class="partner-data"><div class="partner-HP"><div class="HP-fill" style="width:74.06%"><div class="HP-fill-in"><span>74.06%</span></div></div></div></div><div class="partner-level"><span>1148</span><span>|</span><span>1550</span><span>lv.27</span></div></div><div class="partner-item"><div class="partner-rank"></div><div class="partner-user"><a alt="" target="_blank" rel="noopener external nofollow noreferrer" href="https://menglei.xyz" data-title="感谢*夢打赏的￥3">*夢</a></div><div class="partner-data"><div class="partner-HP"><div class="HP-fill" style="width:27.33%"><div class="HP-fill-in"><span>27.33%</span></div></div></div></div><div class="partner-level"><span>205</span><span>|</span><span>750</span><span>lv.11</span></div></div><div class="partner-item"><div class="partner-rank"></div><div class="partner-user"><a alt="" target="_blank" rel="noopener external nofollow noreferrer" href="https://www.ijinse.cn" data-title="感谢锦瑟打赏的￥50">锦瑟</a></div><div class="partner-data"><div class="partner-HP"><div class="HP-fill" style="width:69.45%"><div class="HP-fill-in"><span>69.45%</span></div></div></div></div><div class="partner-level"><span>2639</span><span>|</span><span>3800</span><span>lv.72</span></div></div><div class="partner-item"><div class="partner-rank"></div><div class="partner-user"><a alt="" target="_blank" rel="noopener external nofollow noreferrer" href="https://glann.vip" data-title="感谢glann打赏的￥5.01">glann</a></div><div class="partner-data"><div class="partner-HP"><div class="HP-fill" style="width:41.75%"><div class="HP-fill-in"><span>41.75%</span></div></div></div></div><div class="partner-level"><span>334</span><span>|</span><span>800</span><span>lv.12</span></div></div><div class="partner-item"><div class="partner-rank"></div><div class="partner-user"><a alt="" href="javascript:void(0);" rel="external nofollow noreferrer" data-title="感谢**忠打赏的￥4.48">**忠</a></div><div class="partner-data"><div class="partner-HP"><div class="HP-fill" style="width:89.56%"><div class="HP-fill-in"><span>89.56%</span></div></div></div></div><div class="partner-level"><span>403</span><span>|</span><span>450</span><span>lv.5</span></div></div><div class="partner-item"><div class="partner-rank"></div><div class="partner-user"><a alt="" target="_blank" rel="noopener external nofollow noreferrer" href="https://huran.xyz" data-title="感谢忽然打赏的￥13.14">忽然</a></div><div class="partner-data"><div class="partner-HP"><div class="HP-fill" style="width:87.58%"><div class="HP-fill-in"><span>87.58%</span></div></div></div></div><div class="partner-level"><span>832</span><span>|</span><span>950</span><span>lv.15</span></div></div><div class="partner-item"><div class="partner-rank"></div><div class="partner-user"><a alt="" href="javascript:void(0);" rel="external nofollow noreferrer" data-title="感谢XueZha打赏的￥6.66">XueZha</a></div><div class="partner-data"><div class="partner-HP"><div class="HP-fill" style="width:66.57%"><div class="HP-fill-in"><span>66.57%</span></div></div></div></div><div class="partner-level"><span>466</span><span>|</span><span>700</span><span>lv.10</span></div></div><div class="partner-item"><div class="partner-rank"></div><div class="partner-user"><a alt="" href="javascript:void(0);" rel="external nofollow noreferrer" data-title="感谢*葵打赏的￥6.66">*葵</a></div><div class="partner-data"><div class="partner-HP"><div class="HP-fill" style="width:66.57%"><div class="HP-fill-in"><span>66.57%</span></div></div></div></div><div class="partner-level"><span>466</span><span>|</span><span>700</span><span>lv.10</span></div></div><div class="partner-item"><div class="partner-rank"></div><div class="partner-user"><a alt="" target="_blank" rel="noopener external nofollow noreferrer" href="https://tianli-blog.club" data-title="感谢天利打赏的￥40.34">天利</a></div><div class="partner-data"><div class="partner-HP"><div class="HP-fill" style="width:77.57%"><div class="HP-fill-in"><span>77.57%</span></div></div></div></div><div class="partner-level"><span>2172</span><span>|</span><span>2800</span><span>lv.52</span></div></div><div class="partner-item"><div class="partner-rank"></div><div class="partner-user"><a alt="" target="_blank" rel="noopener external nofollow noreferrer" href="https://bingmeng158.github.io" data-title="感谢冰梦打赏的￥1.5">冰梦</a></div><div class="partner-data"><div class="partner-HP"><div class="HP-fill" style="width:30%"><div class="HP-fill-in"><span>30.00%</span></div></div></div></div><div class="partner-level"><span>135</span><span>|</span><span>450</span><span>lv.5</span></div></div><div class="partner-item"><div class="partner-rank"></div><div class="partner-user"><a alt="" target="_blank" rel="noopener external nofollow noreferrer" href="https://0410wzn.top" data-title="感谢WZN打赏的￥1.35">WZN</a></div><div class="partner-data"><div class="partner-HP"><div class="HP-fill" style="width:27.11%"><div class="HP-fill-in"><span>27.11%</span></div></div></div></div><div class="partner-level"><span>122</span><span>|</span><span>450</span><span>lv.5</span></div></div><div class="partner-item"><div class="partner-rank"></div><div class="partner-user"><a alt="" href="javascript:void(0);" rel="external nofollow noreferrer" data-title="感谢KD打赏的￥1.5">KD</a></div><div class="partner-data"><div class="partner-HP"><div class="HP-fill" style="width:30%"><div class="HP-fill-in"><span>30.00%</span></div></div></div></div><div class="partner-level"><span>135</span><span>|</span><span>450</span><span>lv.5</span></div></div><div class="partner-item"><div class="partner-rank"></div><div class="partner-user"><a alt="" href="javascript:void(0);" rel="external nofollow noreferrer" data-title="感谢**庆打赏的￥3.5">**庆</a></div><div class="partner-data"><div class="partner-HP"><div class="HP-fill" style="width:70%"><div class="HP-fill-in"><span>70.00%</span></div></div></div></div><div class="partner-level"><span>315</span><span>|</span><span>450</span><span>lv.5</span></div></div><div class="partner-item"><div class="partner-rank"></div><div class="partner-user"><a alt="" target="_blank" rel="noopener external nofollow noreferrer" href="https://www.sunguoqi.com" data-title="感谢小孙打赏的￥5.2">小孙</a></div><div class="partner-data"><div class="partner-HP"><div class="HP-fill" style="width:52%"><div class="HP-fill-in"><span>52.00%</span></div></div></div></div><div class="partner-level"><span>364</span><span>|</span><span>700</span><span>lv.10</span></div></div><div class="partner-item"><div class="partner-rank"></div><div class="partner-user"><a alt="" target="_blank" rel="noopener external nofollow noreferrer" href="https://blog.nalex.top" data-title="感谢rootlex打赏的￥4">rootlex</a></div><div class="partner-data"><div class="partner-HP"><div class="HP-fill" style="width:80%"><div class="HP-fill-in"><span>80.00%</span></div></div></div></div><div class="partner-level"><span>360</span><span>|</span><span>450</span><span>lv.5</span></div></div><div class="partner-item"><div class="partner-rank"></div><div class="partner-user"><a alt="" target="_blank" rel="noopener external nofollow noreferrer" href="https://dreamfall.cn" data-title="感谢梦落打赏的￥1.88">梦落</a></div><div class="partner-data"><div class="partner-HP"><div class="HP-fill" style="width:37.56%"><div class="HP-fill-in"><span>37.56%</span></div></div></div></div><div class="partner-level"><span>169</span><span>|</span><span>450</span><span>lv.5</span></div></div><div class="partner-item"><div class="partner-rank"></div><div class="partner-user"><a alt="" target="_blank" rel="noopener external nofollow noreferrer" href="https://blog.cyfan.top" data-title="感谢CYF打赏的￥1.5">CYF</a></div><div class="partner-data"><div class="partner-HP"><div class="HP-fill" style="width:30%"><div class="HP-fill-in"><span>30.00%</span></div></div></div></div><div class="partner-level"><span>135</span><span>|</span><span>450</span><span>lv.5</span></div></div><div class="partner-item"><div class="partner-rank"></div><div class="partner-user"><a alt="" href="javascript:void(0);" rel="external nofollow noreferrer" data-title="感谢一悲打赏的￥2.5">一悲</a></div><div class="partner-data"><div class="partner-HP"><div class="HP-fill" style="width:41.6%"><div class="HP-fill-in"><span>41.60%</span></div></div></div></div><div class="partner-level"><span>208</span><span>|</span><span>500</span><span>lv.6</span></div></div><div class="partner-item"><div class="partner-rank"></div><div class="partner-user"><a alt="" target="_blank" rel="noopener external nofollow noreferrer" href="https://hexo.cf" data-title="感谢八神打赏的￥10">八神</a></div><div class="partner-data"><div class="partner-HP"><div class="HP-fill" style="width:83.38%"><div class="HP-fill-in"><span>83.38%</span></div></div></div></div><div class="partner-level"><span>667</span><span>|</span><span>800</span><span>lv.12</span></div></div><div class="partner-item"><div class="partner-rank"></div><div class="partner-user"><a alt="" target="_blank" rel="noopener external nofollow noreferrer" href="https://noionion.top" data-title="感谢贰猹打赏的￥20">贰猹</a></div><div class="partner-data"><div class="partner-HP"><div class="HP-fill" style="width:90.92%"><div class="HP-fill-in"><span>90.92%</span></div></div></div></div><div class="partner-level"><span>1182</span><span>|</span><span>1300</span><span>lv.22</span></div></div><div class="partner-item"><div class="partner-rank"></div><div class="partner-user"><a alt="" target="_blank" rel="noopener external nofollow noreferrer" href="https://blog.slqwq.cn" data-title="感谢Hajeekn打赏的￥10">Hajeekn</a></div><div class="partner-data"><div class="partner-HP"><div class="HP-fill" style="width:66.63%"><div class="HP-fill-in"><span>66.63%</span></div></div></div></div><div class="partner-level"><span>633</span><span>|</span><span>950</span><span>lv.15</span></div></div><div class="partner-item"><div class="partner-rank"></div><div class="partner-user"><a alt="" target="_blank" rel="noopener external nofollow noreferrer" href="https://baokan0.com" data-title="感谢baokan0打赏的￥20">baokan0</a></div><div class="partner-data"><div class="partner-HP"><div class="HP-fill" style="width:95.2%"><div class="HP-fill-in"><span>95.20%</span></div></div></div></div><div class="partner-level"><span>1190</span><span>|</span><span>1250</span><span>lv.21</span></div></div><div class="partner-item"><div class="partner-rank"></div><div class="partner-user"><a alt="" href="javascript:void(0);" rel="external nofollow noreferrer" data-title="感谢h*d打赏的￥10">h*d</a></div><div class="partner-data"><div class="partner-HP"><div class="HP-fill" style="width:66.63%"><div class="HP-fill-in"><span>66.63%</span></div></div></div></div><div class="partner-level"><span>633</span><span>|</span><span>950</span><span>lv.15</span></div></div><div class="partner-item"><div class="partner-rank"></div><div class="partner-user"><a alt="" href="javascript:void(0);" rel="external nofollow noreferrer" data-title="感谢**航打赏的￥10">**航</a></div><div class="partner-data"><div class="partner-HP"><div class="HP-fill" style="width:66.63%"><div class="HP-fill-in"><span>66.63%</span></div></div></div></div><div class="partner-level"><span>633</span><span>|</span><span>950</span><span>lv.15</span></div></div><div class="partner-item"><div class="partner-rank"></div><div class="partner-user"><a alt="" href="javascript:void(0);" rel="external nofollow noreferrer" data-title="感谢I*u打赏的￥2">I*u</a></div><div class="partner-data"><div class="partner-HP"><div class="HP-fill" style="width:40%"><div class="HP-fill-in"><span>40.00%</span></div></div></div></div><div class="partner-level"><span>180</span><span>|</span><span>450</span><span>lv.5</span></div></div><div class="partner-item"><div class="partner-rank"></div><div class="partner-user"><a alt="" href="javascript:void(0);" rel="external nofollow noreferrer" data-title="感谢7*i打赏的￥1">7*i</a></div><div class="partner-data"><div class="partner-HP"><div class="HP-fill" style="width:20%"><div class="HP-fill-in"><span>20.00%</span></div></div></div></div><div class="partner-level"><span>90</span><span>|</span><span>450</span><span>lv.5</span></div></div></div></div><script async src="https://npm.elemecdn.com/akiblog@1.0.1/js/custom/SAO_ranklist.js"></script><div class="pjax-reload"><script async>for(var arr=document.getElementsByClassName("recent-post-item"),i=0;i<arr.length;i++)arr[i].classList.add("wow"),arr[i].classList.add("animate__zoomIn"),arr[i].setAttribute("data-wow-duration",""),arr[i].setAttribute("data-wow-delay",""),arr[i].setAttribute("data-wow-offset",""),arr[i].setAttribute("data-wow-iteration","")</script><script async>for(var arr=document.getElementsByClassName("card-widget"),i=0;i<arr.length;i++)arr[i].classList.add("wow"),arr[i].classList.add("animate__zoomIn"),arr[i].setAttribute("data-wow-duration",""),arr[i].setAttribute("data-wow-delay",""),arr[i].setAttribute("data-wow-offset",""),arr[i].setAttribute("data-wow-iteration","")</script><script async>for(var arr=document.getElementsByClassName("article-sort-item"),i=0;i<arr.length;i++)arr[i].classList.add("wow"),arr[i].classList.add("animate__zoomIn"),arr[i].setAttribute("data-wow-duration",""),arr[i].setAttribute("data-wow-delay",""),arr[i].setAttribute("data-wow-offset",""),arr[i].setAttribute("data-wow-iteration","")</script><script async>for(var arr=document.getElementsByClassName("flink-list-card"),i=0;i<arr.length;i++)arr[i].classList.add("wow"),arr[i].classList.add("animate__flipInY"),arr[i].setAttribute("data-wow-duration","1s"),arr[i].setAttribute("data-wow-delay",""),arr[i].setAttribute("data-wow-offset",""),arr[i].setAttribute("data-wow-iteration","")</script></div><script defer src="https://npm.elemecdn.com/akiblog@1.0.1/js/custom/wow.min.js"></script><script defer src="https://npm.elemecdn.com/akiblog@1.0.1/js/custom/wow_init.js"></script><div id="fixedcard-dashboard"><button class="fixedcard-activebtn" type="button" title="用户信息" onclick="FixedCardWidget(&quot;class&quot;,&quot;card-author&quot;,&quot;0&quot;)"><i class="fas fa-address-book"></i></button><button class="fixedcard-activebtn" type="button" title="相关推荐" onclick="FixedCardWidget(&quot;class&quot;,&quot;card-recommend-post&quot;,&quot;0&quot;)"><i class="fas fa-dharmachakra"></i></button><div class="fixedcard-user-avatar fixedcard-activebtn" onclick="RemoveFixedCardWidget()"><img class="fixedcard-user-avatar-img" src="" data-lazy-src="https://npm.elemecdn.com/akiblog@1.0.1/img/author.webp" title="Akilar"></div></div><script defer data-pjax src="https://npm.elemecdn.com/akiblog@1.0.1/js/custom/fixed_card_widget.js"></script><script defer data-pjax src="https://npm.elemecdn.com/akiblog@1.0.1/js/custom/fixed_comment.js"></script></div><script>var fdata={apiurl:"/json/akifcircle.json",initnumber:20,stepnumber:10,error_img:"https://npm.elemecdn.com/akilar-candyassets/image/404.gif"};localStorage.setItem("fdatalist",JSON.stringify(fdata))</script><script defer src="https://npm.elemecdn.com/hexo-filter-fcircle/assets/js/fetch.js"></script><script data-pjax src="https://npm.elemecdn.com/hexo-filter-gitcalendar/lib/gitcalendar.js"></script><script data-pjax>function gitcalendar_injector_config(){document.getElementById("recent-posts").insertAdjacentHTML("afterbegin",'<div class="recent-post-item" id="gitcalendarBar" style="width:100%;height:auto;padding:10px;"><style>#git_container{min-height: 280px}@media screen and (max-width:650px) {#git_container{min-height: 0px}}</style><div id="git_loading" style="width:10%;height:100%;margin:0 auto;display: block;"><svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 50 50" style="enable-background:new 0 0 50 50" xml:space="preserve"><path fill="#d0d0d0" d="M25.251,6.461c-10.318,0-18.683,8.365-18.683,18.683h4.068c0-8.071,6.543-14.615,14.615-14.615V6.461z" transform="rotate(275.098 25 25)"><animatetransform attributeType="xml" attributeName="transform" type="rotate" from="0 25 25" to="360 25 25" dur="0.6s" repeatCount="indefinite"></animatetransform></path></svg><style>#git_container{display: none;}</style></div><div id="git_container"></div></div>'),console.log("已挂载gitcalendar")}document.getElementById("recent-posts")&&"/"===location.pathname&&(gitcalendar_injector_config(),GitCalendarInit("/json/akicalendar.json",["#e4dfd7","#f9f4dc","#f7e8aa","#f7e8aa","#f8df72","#fcd217","#fcc515","#f28e16","#fb8b05","#d85916","#f43e06"],"Akilarlxh"))</script></body></html>